Amazon DynamoDB トランザクション: 仕組み - Amazon DynamoDB

「翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。」

Amazon DynamoDB トランザクション: 仕組み

Amazon DynamoDB トランザクションを使用すると、複数のアクションをまとめてグループ化し、1 つのオールオアナッシングの TransactWriteItems または TransactGetItems オペレーションとして送信できます。以下のセクションでは、API オペレーション、容量管理、ベストプラクティス、DynamoDB でのトランザクション操作の使用に関する他の詳細について説明します。

TransactWriteItems API

TransactWriteItems は、最大 25 の書き込みアクションを 1 つのオールオアナッシングオペレーションにグループ化する、同期的でべき等な書き込みオペレーションです。These actions can target up to 25 distinct items in one or more DynamoDB tables within the same AWS account and in the same Region. トランザクション内のアイテムの合計サイズは 4 MB を超えることはできません。すべて成功するかどれも成功しないかのどちらとなるように、アトミックに実行されます。

TransactWriteItems オペレーションは、含まれるすべてのアクションを正常に完了する必要があり、そうでない場合は変更がまったく行われないという点で BatchWriteItem オペレーションとは異なります。BatchWriteItem オペレーションでは、バッチ内の一部のアクションのみ成功し、他のアクションは成功しないことがあり得ます。

同じトランザクション内の複数のオペレーションが同じ項目をターゲットとすることはできません。たとえば、同じトランザクション内で同じ項目に対して ConditionCheck を実行し、Update アクションも実行することはできません。

以下のタイプのアクションをトランザクションに追加できます。

  • Put — PutItem オペレーションを開始し、条件付きで、または条件をまったく指定せずに、新しい項目を作成するか、古い項目を新しい項目に置き換えます。

  • Update — UpdateItem オペレーションを開始し、既存の項目の属性を編集するか、まだ存在しない場合は新しい項目をテーブルに追加します。条件付きまたは条件なしで既存の項目で属性を追加、削除、更新するには、このアクションを使用します。

  • Delete — DeleteItem オペレーションを開始し、プライマリキーにより識別される 1 つの項目をテーブルで削除します。

  • ConditionCheck — 項目が存在することを確認するか、項目の特定の属性の条件を確認します。

トランザクションが完了すると、そのトランザクションによって加えられた変更は、グローバルセカンダリインデックス (GSI)、ストリーム、バックアップに反映されます。反映は、即座に実行されないため、反映中の時点でテーブルがバックアップから復元された場合、最近のトランザクション中に行われた変更の一部のみが含まれる可能性があります。

Idempotency

TransactWriteItems 呼び出しを行ってリクエストがべき等であることを確認するとき、オプションでクライアントトークンを含めることができます。トランザクションをべき等にすると、接続のタイムアウトや他の接続の問題のために同じオペレーションが複数回送信された場合に、アプリケーションエラーを防ぐことができます。

元の TransactWriteItems 呼び出しが成功した場合、同じクライアントトークンを使用したその後の TransactWriteItems 呼び出しが変更を加えずに正常に結果を返します。ReturnConsumedCapacity パラメータが設定されている場合、最初の TransactWriteItems 呼び出しは変更時に消費された書き込みキャパシティーユニットの数を返します。同じクライアントトークンを持つその後の TransactWriteItems 呼び出しは、項目の読み取り時に消費された読み込みキャパシティーユニットの数を返します。

べき等性について重要な点

  • クライアントトークンは、それを使用するリクエストが完了してから 10 分間有効です。10 分後、同じクライアントトークンを使用するリクエストは新しいリクエストとして扱われます。10 分が経過してから、同じリクエストに同じクライアントトークンを再利用しないでください。

  • 10 分間のべき等性期間内に同じクライアントトークンを使用してリクエストを繰り返すとき、他の一部のリクエストパラメータを変更した場合、DynamoDB は IdempotentParameterMismatch 例外を返します。

書き込みのエラー処理

以下の条件下では、書き込みトランザクションが成功しません。

  • いずれかの条件式の条件が満たされていない場合。

  • 同じ TransactWriteItems オペレーション内の複数のアクションが同じ項目をターゲットとしているために、トランザクション検証エラーが発生した場合。

  • TransactWriteItems リクエストが、TransactWriteItems リクエスト内の 1 つ以上の項目に対する継続中の TransactWriteItems オペレーションと競合する場合。この場合、リクエストは TransactionCanceledException で失敗します。

  • トランザクションを完了するプロビジョンドキャパシティーが足りない場合。

  • 項目サイズが大きくなりすぎる (400 KB 超)、ローカルセカンダリインデックス (LSI) が大きくなりすぎる、またはトランザクションにより変更が加えられたために同様の検証エラーが発生した場合。

  • 無効なデータ形式などのユーザーエラーがある場合。

TransactWriteItems オペレーションとの競合がどのように処理されるかについて詳しくは、「DynamoDB でのトランザクション競合の処理」を参照してください。

TransactGetItems API

TransactGetItems は、最大 25 個の Get アクションをまとめてグループ化する同期読み取りオペレーションです。These actions can target up to 25 distinct items in one or more DynamoDB tables within the same AWS account and Region. トランザクション内の項目の合計サイズは 4 MB を超えることはできません。

Get アクションは、すべて成功するかすべて失敗するかのどちらとなるように、アトミックに実行されます。

  • Get — GetItem オペレーションを開始し、指定されたプライマリキーを持つ項目の属性のセットを取得します。一致する項目が見つからない場合、Get はデータを返しません。

読み取りのエラー処理

以下の条件下では、読み取りトランザクションが成功しません。

  • TransactGetItems リクエストが、TransactWriteItems リクエスト内の 1 つ以上の項目に対する継続中の TransactGetItems オペレーションと競合する場合。この場合、リクエストは TransactionCanceledException で失敗します。

  • トランザクションを完了するプロビジョンドキャパシティーが足りない場合。

  • 無効なデータ形式などのユーザーエラーがある場合。

TransactGetItems オペレーションとの競合がどのように処理されるかについて詳しくは、「DynamoDB でのトランザクション競合の処理」を参照してください。

DynamoDB トランザクションの分離レベル

トランザクションオペレーション (TransactWriteItems または TransactGetItems) と他のオペレーションの分離レベルは、次のとおりです。

SERIALIZABLE

直列化可能分離レベルでは、複数の同時オペレーションの結果は、前のオペレーションが完了するまでオペレーションが開始されない場合と同じになります。

以下のタイプのオペレーション間には、直列化可能分離があります。

  • トランザクションオペレーションと標準書き込みオペレーション (PutItemUpdateItem、または DeleteItem) の間。

  • トランザクションオペレーションと標準読み取りオペレーション (GetItem) の間。

  • Between a TransactWriteItems operation and a TransactGetItems operation.

トランザクションオペレーション間と BatchWriteItem オペレーション内の個々の標準書き込み間には直列化可能分離がありますが、トランザクションとユニットとしての BatchWriteItem オペレーションの間には直列化可能分離はありません。

同様に、トランザクションオペレーションと GetItems オペレーションの個別の BatchGetItem 間の分離レベルは直列化可能です。ただし、トランザクションとユニットとしての BatchGetItem オペレーション間の分離レベルはコミット済み読み取りです。

A single GetItem request is serializable with respect to a TransactWriteItems request in one of two ways, either before or after the TransactWriteItems request. Multiple GetItem requests, against keys in a concurrent TransactWriteItems requests can be run in any order, and therefore the results are read-committed.

For example, if GetItem requests for item A and item B are run concurrently with a TransactWriteItems request that modifies both item A and item B, there are four possibilities:

  • Both GetItem requests are run before the TransactWriteItems request.

  • Both GetItem requests are run after the TransactWriteItems request.

  • GetItem request for item A is run before the TransactWriteItems request. For item B the GetItem is run after TransactWriteItems.

  • GetItem request for item B is run before the TransactWriteItems request. For item A the GetItem is run after TransactWriteItems.

If serializable isolation level is preferred for multiple GetItem requests, then please use TransactGetItems.

コミット済み読み取り

コミット済み読み取り分離では、読み取りオペレーションが常に項目のコミット済み値を返します。コミット済み読み取り分離では、読み取りオペレーションの直後に項目の変更が防止されません。

分離レベルは、トランザクションオペレーションと、複数の標準読み取り (BatchGetItemQuery、または Scan) が関係する読み取りオペレーションの間ではコミット済み読み取りです。トランザクション書き込みにより BatchGetItemQuery、または Scan オペレーションの途中で項目が更新された場合、読み取りオペレーションは新しいコミット済み値を返します。

オペレーションの概要

以下の表は、トランザクションオペレーション (TransactWriteItems または TransactGetItems) と他のオペレーションの間の分離レベルをまとめたものです。

オペレーション 分離レベル

DeleteItem

直列化可能

PutItem

直列化可能

UpdateItem

直列化可能

GetItem

直列化可能

BatchGetItem

コミット済み読み取り*

BatchWriteItem

直列化不可*

Query

コミット済み読み取り

Scan

コミット済み読み取り

他のトランザクションオペレーション

直列化可能

アスタリスク (*) が付いたレベルは、ユニットとしてオペレーションに適用されます。ただし、これらのオペレーション内の個々のアクションの分離レベルは直列化可能です。

DynamoDB でのトランザクション競合の処理

トランザクション競合は、トランザクション内の項目に対する項目レベルの同時リクエスト中に発生する場合があります。トランザクション競合は、次のシナリオで発生する場合があります。

  • 項目に対する PutItemUpdateItem、または DeleteItem リクエストが、同じ項目を含む継続中の TransactWriteItems リクエストと競合する。

  • TransactWriteItems リクエスト内の項目が、継続中の別の TransactWriteItems リクエストの一部である。

  • An item within a TransactGetItems request is part of an ongoing TransactWriteItems, BatchWriteItem, PutItem, UpdateItem, or DeleteItem request.

注記
  • When a PutItem, UpdateItem, or DeleteItem request is rejected, the request fails with a TransactionConflictException.

  • TransactWriteItems または TransactGetItems 内の項目レベルのリクエストが拒否された場合、リクエストは TransactionCanceledException で失敗します。If that request fails, AWS SDKs do not retry the request.

    If you are using the AWS SDK for Java, the exception contains the list of CancellationReasons, ordered according to the list of items in the TransactItems request parameter. 他の言語の場合、リストの文字列表現が例外のエラーメッセージに含まれます。

  • 継続中の TransactWriteItems オペレーションまたは TransactGetItems オペレーションが同時 GetItem リクエストと競合している場合、両方のオペレーションが成功する可能性があります。

TransactionConflict CloudWatch メトリクスは、項目レベルのリクエストが失敗するたびに増分されます。

DynamoDB Accelerator (DAX) でトランザクション API を使用する

TransactWriteItemsTransactGetItems が、どちらも DynamoDB Accelerator と同じ分離レベルで DAX (DynamoDB) でサポートされています。

TransactWriteItems は DAX を経由して書き込みます。DAX は TransactWriteItems コールをDynamoDB 渡して、レスポンスを返します。書き込み後にキャッシュにデータを追加するために、DAX は、TransactGetItems オペレーション内の各項目に対してバックグラウンドで TransactWriteItems を呼び出します。これにより、追加の読み取りキャパシティーユニットが消費されます。(詳しくは、トランザクションの容量管理 を参照してください)。この機能により、アプリケーションロジックをシンプルに保ち、トランザクション処理と非トランザクション処理の両方に DAX を使用できます。​

TransactGetItems コールは、項目がローカルにキャッシュされることなく DAX を通過します。​ これは、DAX の強い整合性のある読み込み API と同じです。

トランザクションの容量管理

DynamoDB テーブルのトランザクションを有効にするために、追加料金はかかりません。トランザクションの一部となっている読み取りまたは書き取りにのみ料金が発生します。DynamoDB は、トランザクション内の各項目の基になっている 2 つの読み取りまたは書き込みを実行します。1 つはトランザクションの準備用で、もう 1 つはトランザクションのコミット用です。基になっている 2 つの読み取り/書き込みオペレーションは、Amazon CloudWatch メトリクスに表示されます。

容量をテーブルにプロビジョニングするとき、トランザクション API により要求される追加の読み取りと書き込みを計画してください。For example, suppose that your application runs one transaction per second, and each transaction writes three 500-byte items in your table. 各項目には、2 つの書き込みキャパシティーユニット (WCU) が必要です。1 つはトランザクションの準備用で、もう 1 つはトランザクションのコミット用です。したがって、テーブルには WCU を 6 個プロビジョニングする必要があります。

前の例で DynamoDB Accelerator (DAX) を使用していた場合、TransactWriteItems の呼び出しで項目ごとに 2 つの読み込みキャパシティーユニット (RCU) も使用します。したがって、テーブルには追加の RCU を 6 個プロビジョニングする必要があります。

Similarly, if your application runs one read transaction per second, and each transaction reads three 500-byte items in your table, you would need to provision six read capacity units (RCUs) to the table. 各項目を読み取るには、2 つの RCU が必要です。1 つはトランザクションの準備用で、もう 1 つはトランザクションのコミット用です。

さらに、SDK のデフォルトの動作は、TransactionInProgressException 例外が発生した場合にトランザクションを再試行します。これらの再試行で消費される追加の読み込みキャパシティーユニット (RCU) を計画してください。同じことは、ClientRequestToken を使用して独自のコードでトランザクションを再試行しようとする場合に当てはまります。

トランザクションのベストプラクティス

DynamoDB トランザクションの使用時に推奨される以下の手法を検討してください。

  • テーブルで自動スケーリングを有効にするか、トランザクションの項目ごとに 2 つの読み取りまたは書き込みオペレーションを実行するのに十分なスループット容量をプロビジョニングしたことを確認します。

  • If you are not using an AWS provided SDK, include a ClientRequestToken attribute when you make a TransactWriteItems call to ensure that the request is idempotent.

  • 必要でない場合は、トランザクションにオペレーションをまとめてグループ化しないでください。たとえば、10 個のオペレーションを持つ 1 つのトランザクションを、アプリケーションの正確性を低下させずに複数のトランザクションに分割できる場合、トランザクションを分割することをお勧めします。トランザクションをシンプルにするとスループットが向上し、成功する可能性が高まります。

  • 同じ項目を同時に更新する複数のトランザクションによって、トランザクションをキャンセルする競合が発生する可能性があります。そのような競合を最小限に抑えるため、データモデリングには以下の DynamoDB のベストプラクティスをお勧めします。

  • 属性のセットが 1 つのトランザクションの一部として複数の項目間で頻繁に更新される場合、属性を 1 つの項目にグループ化し、トランザクションのスコープを減らすことを検討してください。

  • データを大量に取り込むためにトランザクションを使用しないでください。一括書き込みには、BatchWriteItem の使用をお勧めします。

グローバルテーブルでのトランザクション API の使用

トランザクションオペレーションは、書き込みが最初に行われたリージョン内でのみ、不可分性、一貫性、分離性、および耐久性 (ACID) を保証します。グローバルテーブルのリージョン間では、トランザクションはサポートされていません。たとえば、米国東部(オハイオ)および米国西部(オレゴン)リージョンにレプリカを持つグローバルテーブルがあり、米国東部(バージニア北部)リージョンで TransactWriteItems オペレーションを実行する場合、変更がレプリケートされると米国西部(オレゴン)で部分的に完了したトランザクションを確認できます。変更は、ソースリージョンでコミットされると、他のリージョンにのみレプリケートされます。

DynamoDB トランザクションと AWSLabs トランザクションクライアントライブラリ

DynamoDB トランザクションには、AWSLabs トランザクションクライアントライブラリを置き換えるより費用効率、堅牢性、パフォーマンスに優れた手段が用意されています。ネイティブのサーバー側トランザクション API を使用するようにアプリケーションを更新することをお勧めします。