DynamoDB용 PartiQL에서 트랜잭션 수행
이 단원에서는 DynamoDB용 PartiQL에서 트랜잭션을 사용하는 방법을 설명합니다. PartiQL 트랜잭션은 총 100개의 명령문(작업)으로 제한됩니다.
DynamoDB 트랜잭션에 대한 자세한 내용은 DynamoDB Transactions를 사용하여 복잡한 워크플로 관리를 참조하세요.
전체 트랜잭션은 읽기 또는 쓰기 문으로 구성해야 합니다. 하나의 트랜잭션에서 두 가지를 모두 혼용할 수는 없습니다. EXISTS 함수는 예외입니다. TransactWriteItems API 작업의 ConditionCheck
와 유사한 방식으로 특정 항목 속성의 조건을 확인하는 데 사용할 수 있습니다.
구문
[
{
"Statement":" statement
",
"Parameters":[
{
" parametertype
" : " parametervalue
"
}, ...]
} , ...
]
파라미터
설명
-
(필수) DynamoDB용 PartiQL에서 지원되는 문입니다.
전체 트랜잭션은 읽기 또는 쓰기 문으로 구성해야 합니다. 하나의 트랜잭션에서 두 가지를 모두 혼용할 수는 없습니다.
parametertype
-
(선택 사항) ParitPartiQL 문을 지정할 때 파라미터가 사용된 경우 DynamoDB 형식입니다.
parametervalue
-
(선택 사항) PartiQL 문을 지정할 때 파라미터가 사용된 경우 파라미터 값입니다.
반환 값
이 문은 쓰기 작업(INSERT, UPDATE 또는 DELETE)에 대한 값을 반환하지 않습니다. 그러나 WHERE 절에 지정된 조건에 따라 읽기 작업 (SELECT) 에 대해 서로 다른 값을 반환합니다.
Singleton INSERT, UPDATE 또는 DELETE 작업 중 하나에서 오류를 반환하는 경우 트랜잭션이 TransactionCanceledException
예외로 취소되고 취소 이유 코드에 개별 singleton 작업의 오류가 포함됩니다.
예
다음 예는 여러 문을 트랜잭션으로 실행합니다.
- AWS CLI
-
-
다음 JSON 코드를 partiql.json이라는 파일에 저장합니다.
[
{
"Statement": "EXISTS(SELECT * FROM \"Music\" where Artist='No One You Know' and SongTitle='Call Me Today' and Awards is MISSING)"
},
{
"Statement": "INSERT INTO Music value {'Artist':?,'SongTitle':'?'}",
"Parameters": [{\"S\": \"Acme Band\"}, {\"S\": \"Best Song\"}]
},
{
"Statement": "UPDATE \"Music\" SET AwardsWon=1 SET AwardDetail={'Grammys':[2020, 2018]} where Artist='Acme Band' and SongTitle='PartiQL Rocks'"
}
]
-
명령 프롬프트에서 다음 명령을 실행합니다.
aws dynamodb execute-transaction --transact-statements file://partiql.json
- Java
-
public class DynamoDBPartiqlTransaction {
public static void main(String[] args) {
// Create the DynamoDB Client with the region you want
AmazonDynamoDB dynamoDB = createDynamoDbClient("us-west-2");
try {
// Create ExecuteTransactionRequest
ExecuteTransactionRequest executeTransactionRequest = createExecuteTransactionRequest();
ExecuteTransactionResult executeTransactionResult = dynamoDB.executeTransaction(executeTransactionRequest);
System.out.println("ExecuteTransaction successful.");
// Handle executeTransactionResult
} catch (Exception e) {
handleExecuteTransactionErrors(e);
}
}
private static AmazonDynamoDB createDynamoDbClient(String region) {
return AmazonDynamoDBClientBuilder.standard().withRegion(region).build();
}
private static ExecuteTransactionRequest createExecuteTransactionRequest() {
ExecuteTransactionRequest request = new ExecuteTransactionRequest();
// Create statements
List<ParameterizedStatement> statements = getPartiQLTransactionStatements();
request.setTransactStatements(statements);
return request;
}
private static List<ParameterizedStatement> getPartiQLTransactionStatements() {
List<ParameterizedStatement> statements = new ArrayList<ParameterizedStatement>();
statements.add(new ParameterizedStatement()
.withStatement("EXISTS(SELECT * FROM "Music" where Artist='No One You Know' and SongTitle='Call Me Today' and Awards is MISSING)"));
statements.add(new ParameterizedStatement()
.withStatement("INSERT INTO "Music" value {'Artist':'?','SongTitle':'?'}")
.withParameters(new AttributeValue("Acme Band"),new AttributeValue("Best Song")));
statements.add(new ParameterizedStatement()
.withStatement("UPDATE "Music" SET AwardsWon=1 SET AwardDetail={'Grammys':[2020, 2018]} where Artist='Acme Band' and SongTitle='PartiQL Rocks'"));
return statements;
}
// Handles errors during ExecuteTransaction execution. Use recommendations in error messages below to add error handling specific to
// your application use-case.
private static void handleExecuteTransactionErrors(Exception exception) {
try {
throw exception;
} catch (TransactionCanceledException tce) {
System.out.println("Transaction Cancelled, implies a client issue, fix before retrying. Error: " + tce.getErrorMessage());
} catch (TransactionInProgressException tipe) {
System.out.println("The transaction with the given request token is already in progress, consider changing " +
"retry strategy for this type of error. Error: " + tipe.getErrorMessage());
} catch (IdempotentParameterMismatchException ipme) {
System.out.println("Request rejected because it was retried with a different payload but with a request token that was already used, " +
"change request token for this payload to be accepted. Error: " + ipme.getErrorMessage());
} catch (Exception e) {
handleCommonErrors(e);
}
}
private static void handleCommonErrors(Exception exception) {
try {
throw exception;
} catch (InternalServerErrorException isee) {
System.out.println("Internal Server Error, generally safe to retry with exponential back-off. Error: " + isee.getErrorMessage());
} catch (RequestLimitExceededException rlee) {
System.out.println("Throughput exceeds the current throughput limit for your account, increase account level throughput before " +
"retrying. Error: " + rlee.getErrorMessage());
} catch (ProvisionedThroughputExceededException ptee) {
System.out.println("Request rate is too high. If you're using a custom retry strategy make sure to retry with exponential back-off. " +
"Otherwise consider reducing frequency of requests or increasing provisioned capacity for your table or secondary index. Error: " +
ptee.getErrorMessage());
} catch (ResourceNotFoundException rnfe) {
System.out.println("One of the tables was not found, verify table exists before retrying. Error: " + rnfe.getErrorMessage());
} catch (AmazonServiceException ase) {
System.out.println("An AmazonServiceException occurred, indicates that the request was correctly transmitted to the DynamoDB " +
"service, but for some reason, the service was not able to process it, and returned an error response instead. Investigate and " +
"configure retry strategy. Error type: " + ase.getErrorType() + ". Error message: " + ase.getErrorMessage());
} catch (AmazonClientException ace) {
System.out.println("An AmazonClientException occurred, indicates that the client was unable to get a response from DynamoDB " +
"service, or the client was unable to parse the response from the service. Investigate and configure retry strategy. "+
"Error: " + ace.getMessage());
} catch (Exception e) {
System.out.println("An exception occurred, investigate and configure retry strategy. Error: " + e.getMessage());
}
}
}
다음 예제에서는 DynamoDB가 WHERE 절에 지정된 조건이 다른 항목을 읽을 때 서로 다른 반환 값을 보여줍니다.
- AWS CLI
-
-
다음 JSON 코드를 partiql.json이라는 파일에 저장합니다.
[
// Item exists and projected attribute exists
{
"Statement": "SELECT * FROM "Music" WHERE Artist='No One You Know' and SongTitle='Call Me Today'"
},
// Item exists but projected attributes do not exist
{
"Statement": "SELECT non_existent_projected_attribute FROM "Music" WHERE Artist='No One You Know' and SongTitle='Call Me Today'"
},
// Item does not exist
{
"Statement": "SELECT * FROM "Music" WHERE Artist='No One I Know' and SongTitle='Call You Today'"
}
]
-
명령 프롬프트에서 다음 명령.
aws dynamodb execute-transaction --transact-statements file://partiql.json
-
다음 응답이 반환됩니다.
{
"Responses": [
// Item exists and projected attribute exists
{
"Item": {
"Artist":{
"S": "No One You Know"
},
"SongTitle":{
"S": "Call Me Today"
}
}
},
// Item exists but projected attributes do not exist
{
"Item": {}
},
// Item does not exist
{}
]
}