DynamoDB で同時更新を処理するためのベストプラクティス
分散システムでは、複数のプロセスまたはユーザーが同時に同じデータを変更しようとすることがあります。同時実行制御がない場合、これらの同時書き込みにより、更新の損失、データの不整合、競合状態が発生する可能性があります。DynamoDB には、同時アクセスの管理とデータ整合性の維持に役立つメカニズムがいくつか用意されています。
注記
UpdateItem などの個々の書き込みオペレーションはアトミックであり、同時実行性に関係なく、常に項目の最新バージョンに対して実行されます。アプリケーションが項目を読み取り、読み取った値に基づいて書き戻す必要がある場合 (読み取り/変更/書き込みサイクル)、読み取りと書き込みの間に別のプロセスが項目を変更する可能性があるため、ロック戦略が必要になります。
同時更新を処理するには、主に 2 つの戦略があります。
-
楽観的ロック — 競合がまれであると想定します。同時アクセスを許可し、条件付き書き込みを使用して書き込み時に競合を検出します。競合が検出されると、書き込みは失敗し、アプリケーションは再試行できます。
-
悲観的ロック — 競合が発生する可能性が高いと想定します。リソースを変更する前に排他的アクセスを取得することで、同時アクセスを防止します。他のプロセスは、ロックが解除されるまで待つ必要があります。
次の表は、DynamoDB で使用できるアプローチをまとめたものです。
| アプローチ | メカニズム | 次の用途に適しています |
|---|---|---|
| オプティミスティックロック | バージョン属性 + 条件付き書き込み | 競合が少なく、再試行コストが低い |
| 悲観的ロック (トランザクション) | TransactWriteItems |
複数項目のアトミック性、中程度の競合 |
| 悲観的ロック (ロッククライアント) | リースとハートビートを備えた専用ロックテーブル | 長時間実行されるワークフロー、分散調整 |
同時実行制御戦略の選択
ワークロードに適したアプローチを選択するには、次のガイドラインを使用します。
- 次の場合は、楽観的ロックを使用します。
-
競合はまれです。
失敗した書き込みを再試行するのは安価です。
一度に 1 つの項目を更新します。
- 次の場合は、トランザクションを使用します。
-
複数の項目をアトミックに更新する必要があります。
項目またはテーブル全体でオールオアナッシングセマンティクスが必要です。
条件チェックと書き込みを 1 つのオペレーションで組み合わせる必要があります。
- 次の場合は、ロッククライアントを使用します。
-
分散プロセス全体で外部リソースへのアクセスを調整する必要があります。
重要なセクションは長時間実行され、競合時の再試行にはコストがかかります。
プロセスの失敗を処理するには、自動ロックの有効期限が必要です。
注記
DynamoDB グローバルテーブルを使用する場合は、グローバルテーブルが同時更新に「最終書き込み者優先」調整戦略を使用することに注意してください。バージョン番号を使用した楽観的ロックは、あるリージョンでの書き込みがバージョンチェックなしで別のリージョンでの同時書き込みを上書きする可能性があるため、リージョン間では期待どおりに機能しません。グローバルテーブルを使用する場合は、アプリケーションレベルで競合を処理するようにアプリケーションを設計します。