AWS CLI를 사용한 DynamoDB TransactWriteItems
트랜잭션 전체가 하나의 --transact-items JSON 배열로 aws dynamodb transact-write-items에 전달되므로, 흥미로운 부분은 CLI 쪽 경계입니다. 인용이 어디서 깨지는지, 종료 코드가 무엇을 뜻하는지, 그리고 기본 오류 출력이 취소를 디버깅하는 데 필요한 필드를 빠뜨린다는 사실 말입니다. 트랜잭션이 무엇을 사 주는지는 어느 SDK에서나 같습니다.
코드
aws dynamodb transact-write-items \
--transact-items '[
{
"Update": {
"TableName": "Music",
"Key": {"Artist": {"S": "Arturo Sandoval"}, "SongTitle": {"S": "Cubano Chant"}},
"UpdateExpression": "SET #upd0 = #upd0 - :one",
"ConditionExpression": "#upd0 >= :one",
"ExpressionAttributeNames": {"#upd0": "Awards"},
"ExpressionAttributeValues": {":one": {"N": "1"}}
}
},
{
"Update": {
"TableName": "Music",
"Key": {"Artist": {"S": "Arturo Sandoval"}, "SongTitle": {"S": "A Mis Abuelos"}},
"UpdateExpression": "SET #upd0 = if_not_exists(#upd0, :zero) + :one",
"ExpressionAttributeNames": {"#upd0": "Awards"},
"ExpressionAttributeValues": {":one": {"N": "1"}, ":zero": {"N": "0"}}
}
}
]'커밋된 트랜잭션은 아무것도 출력하지 않고 0으로 종료합니다. 확인할 응답 본문이 없으므로, 스크립트에서는 종료 코드가 곧 결과입니다.
설명
--transact-items— 최대 100개의Put/Update/Delete/ConditionCheck작업, 합계 4 MB, 값은 DynamoDB JSON입니다. 작업은 같은 계정과 리전 안의 여러 테이블에 걸칠 수 있으며, 그중 둘이 같은 항목을 대상으로 삼을 수는 없습니다.종료 코드 세 가지, 서로 다른 실패 세 가지.
0은 커밋입니다.252는 CLI 자체의 파라미터 검증이 요청을 거부해 아무것도 전송되지 않았다는 뜻입니다.254는 DynamoDB가 답을 했고 거절했다는 뜻입니다. 이 구분은 분기할 값어치가 있습니다. 252는 JSON의 버그이고, 254는 실패하리라 예상했던 조건일 수도 있습니다.기본 오류 형식은 작업별 사유를 빠뜨립니다. aws-cli v2는 요약을 출력한 뒤 세부 정보를 감추고 있다고 알려 줍니다:
aws: [ERROR]: An error occurred (TransactionCanceledException) when calling the TransactWriteItems operation: Transaction cancelled, please refer cancellation reasons for specific reasons [ConditionalCheckFailed, None] Additional error details: CancellationReasons: <complex value> Use "--cli-error-format json" or another error format to see the full details.같은 명령을
--cli-error-format json으로 다시 실행하면 구조가 온전히 도착하며, 작업당 항목 하나씩--transact-items순서대로 나옵니다:{ "Message": "Transaction cancelled, please refer cancellation reasons for specific reasons [ConditionalCheckFailed, None]", "Code": "TransactionCanceledException", "CancellationReasons": [ { "Code": "ConditionalCheckFailed", "Message": "The conditional request failed" }, { "Code": "None" } ] }여기서는 첫 번째 업데이트의
Awards >= 1조건이 실패했습니다.None은 두 번째 작업에 죄가 없다는 표시이며,Message필드를 아예 담고 있지 않다는 점에 유의하세요. 나머지 코드는 모두 TransactionCanceledException 페이지에서 해독합니다.한 항목을 두 번 대상으로 삼는 것은 취소가 아닙니다. 아무것도 시도되기 전에 검증에서 실패하므로, 출력할 사유도 없습니다:
aws: [ERROR]: An error occurred (ValidationException) when calling the TransactWriteItems operation: Transaction request cannot include multiple operations on one itemConditionCheck— 트랜잭션이 수정하지 않는 항목에 조건을 주장하며, 실패하면 트랜잭션 전체를 거부합니다.--client-request-token— 고정된 토큰은 재실행을 10분간 멱등으로 만듭니다. 파라미터를 하나라도 바꾼 채 같은 토큰을 재사용하면 DynamoDB는 새 페이로드를 조용히 적용하는 대신IdempotentParameterMismatch를 반환합니다.배열은 파일에 두세요.
--transact-items file://transaction.json은 셸 인용을 통째로 우회하며, 파일은 diff도 됩니다.
셸에서 2배를 측정할 수 있습니다
같은 단일 항목 업데이트를 트랜잭션 안에서 한 번, 밖에서 한 번, 둘 다 --return-consumed-capacity TOTAL을 붙여 실행해 보세요. DynamoDB Local은 트랜잭션 쓰기에 2.0 용량 단위를, 평범한 쓰기에 1.0을 보고합니다. 준비와 커밋이 각각 과금되기 때문입니다.
이것이 기본적으로 트랜잭션에 손을 뻗지 말아야 한다는 논거의 전부입니다. 항목 하나의 원자성이라면 이미 더 저렴한 도구가 있습니다. 한 번만 과금되는 조건부 쓰기입니다. 이런 일을 수백만 번 하는 워크로드의 값을 매기려면, DynamoDB 요금 계산기가 두 배가 된 쓰기 횟수를 그대로 받습니다. 셸에서 DynamoDB JSON을 조립하는 일을 그만두고 싶은 것이라면, DynoTable이 실제 테이블에 대해 항목을 편집하고 생성된 표현식을 보여 줍니다.
관련 예제
- Node.js의 DynamoDB TransactWriteItems — AWS SDK v3로 하는 같은 트랜잭션.
- Python의 DynamoDB TransactWriteItems — boto3로 하는 같은 트랜잭션.
- AWS CLI를 사용한 DynamoDB BatchWriteItem — 원자성이 필요 없을 때의 대량 쓰기.
- DynamoDB 트랜잭션 — 격리, 멱등성, 그리고 트랜잭션이 값어치를 할 때.
- DynamoDB TransactionCanceledException — 모든 취소 사유 코드 해독.
- "Too many actions in a TransactWriteItems call" — 100개 작업과 4 MB 트랜잭션 한도.
- "Transaction request cannot include multiple operations on one item" — 트랜잭션당 항목마다 작업 하나.
참고 자료
- TransactWriteItems — Amazon DynamoDB API Reference
- transact-write-items — AWS CLI Command Reference
- Amazon DynamoDB transactions: how it works — Amazon DynamoDB Developer Guide
- DynamoDB read and write operations (capacity unit consumption) — Amazon DynamoDB Developer Guide
위에 링크된 공식 AWS 문서를 기준으로 2026-07-28에 마지막으로 검증했습니다.