Python (boto3) での DynamoDB TransactWriteItems
transact_write_items は、最大100個の書き込みを1つのオール・オア・ナッシングの操作にまとめます。すべてのアクションがコミットされるか、まったく何も起きないかのどちらかです。boto3 の低レベルクライアントでは、Put、Update、Delete、ConditionCheck のアクションを混在させた TransactItems リストを渡します。それぞれ任意の条件付きです。
Code
import boto3
client = boto3.client("dynamodb")
# Move one award between two songs — atomically. If the first song has no
# award to give, NEITHER update happens.
try:
client.transact_write_items(
TransactItems=[
{
"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"}},
}
},
]
)
print("Transaction committed")
except client.exceptions.TransactionCanceledException as e:
# One reason per action, in TransactItems order. Code "None" means that
# action was fine — some OTHER action sank the transaction.
codes = [reason["Code"] for reason in e.response["CancellationReasons"]]
print(f"Transaction canceled: {codes}") # e.g. ['ConditionalCheckFailed', 'None']Explanation
TransactItems— 最大100個のPut/Update/Delete/ConditionCheckアクション、集計4 MB、値は DynamoDB JSON。アクションは複数のテーブルにまたがれます(同一アカウント + リージョン)が、2つのアクションが同じアイテムを対象にすることはできません — それだけでトランザクションがキャンセルされます。ConditionCheck— トランザクションが変更しないアイテムに条件をアサートし(例: 「アカウントがまだ存在する」)、失敗した場合はトランザクション全体を拒否します。TransactionCanceledException— 処理すべき唯一のエラーです。e.response["CancellationReasons"]は、アクションごとに1つの{"Code", "Message"}を順に列挙します。コードにはConditionalCheckFailed、TransactionConflict(別のトランザクションが処理中にアイテムに触れた — バックオフ付きでリトライしても安全)、ProvisionedThroughputExceeded、ValidationErrorが含まれます。Noneは無実のアクションを示します。アクションに"ReturnValuesOnConditionCheckFailure": "ALL_OLD"を設定すると、その理由に負けたアイテムの属性が得られます。ClientRequestToken— これを渡すと呼び出しが10分間べき等になります。ネットワークタイムアウト後の botocore リトライで、書き込みを2回適用できなくなります。- コスト — トランザクション書き込みはアイテムごとに2つの基礎的な書き込みを消費し(準備 + コミット)、プレーンな書き込みの約2× の WCU を課金します。単一アイテムの条件付き書き込みがすでに1アイテムのアトミック性を提供しているときは、トランザクションに手を伸ばさないでください。
Do it visually
各アクション内の条件式と更新式が厄介な部分です。DynamoDB Expression Builder がそれらを name/value マップとともに組み立て、実行可能な boto3 コードをコピーします。
アイテムを編集し、生成された式を GUI でレビューするには — DynoTable をダウンロードしてください。
Related examples
- DynamoDB TransactWriteItems in Node.js — AWS SDK v3 での同じトランザクション。
- DynamoDB TransactWriteItems with the AWS CLI — シェルからの同じトランザクション。
- DynamoDB conditional write in Python — 2× のコストなしの単一アイテムのアトミック性。
- DynamoDB transactions — 分離、べき等性、そしてトランザクションが割に合うのはいつか。
- DynamoDB TransactionCanceledException — すべてのキャンセル理由コードを解読。
- "Too many actions in a TransactWriteItems call" — 100アクションと4 MB のトランザクション制限。
- "Transaction request cannot include multiple operations on one item" — トランザクションごと、アイテムごとに1アクション。
References
- TransactWriteItems — Amazon DynamoDB API Reference
- DynamoDB.Client.transact_write_items — Boto3 documentation
- Amazon DynamoDB transactions: how it works — Amazon DynamoDB Developer Guide
- DynamoDB read and write operations (capacity unit consumption) — Amazon DynamoDB Developer Guide
最終検証日 2026-07-13、上記にリンクした公式 AWS ドキュメントに照らして確認しました。