DynamoDB용 PartiQL에서 트랜잭션 수행 - Amazon DynamoDB

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
  1. 다음 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'" } ]
  2. 명령 프롬프트에서 다음 명령을 실행합니다.

    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
  1. 다음 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'" } ]
  2. 명령 프롬프트에서 다음 명령.

    aws dynamodb execute-transaction --transact-statements file://partiql.json
  3. 다음 응답이 반환됩니다.

    { "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 {} ] }