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 item
  • ConditionCheck — 트랜잭션이 수정하지 않는 항목에 조건을 주장하며, 실패하면 트랜잭션 전체를 거부합니다.

  • --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이 실제 테이블에 대해 항목을 편집하고 생성된 표현식을 보여 줍니다.

관련 예제

참고 자료

위에 링크된 공식 AWS 문서를 기준으로 2026-07-28에 마지막으로 검증했습니다.

Console 없이 DynamoDB 작업하기

DynamoDB로는 실행할 수 없는 진짜 SQL(JOINs, GROUP BY, 집계)을 실행하는 빠른 DynamoDB 데스크톱 클라이언트. 시각적 편집과 여러분 자신의 Bedrock 키로 동작하는 AI 에이전트를 제공합니다.

30일 무료 체험, 신용카드 불필요 — 이후 기간 제한 없는 무료 요금제.