Amazon Web Services ブログ
新機能 – DynamoDB Transactions
Amazon DynanmoDBがローンチされてから多くのユースケースで使われてきました。microservicesやゲームなどのモバイルバックエンドシステム、IoTソリューションなど様々です。例えばCapital Oneのユースケースではモバイルアプリケーションから使われていたメインフレームの処理をサーバレスアーキテクチャに移行しレイテンシの軽減にもなりました。TinderはDynamoDBにゼロダウンタイムで移行し、世界中のユーザーのために必要なスケーラビリティを獲得しました。
開発者の多くはビジネスロジックの実装に複数のItemを操作し、all-or-nothingな結果を一つか複数のtableにまたがって行いたいと思う場面があると思います。要件によっては実装に不必要な複雑さが加わることがあります。今日、我々はこのユースケースに対応するためにDynamoDBにtransaction機能をネイティブサポートしました!
Amazon DynamoDB Transactionsについて
DynamoDB transactionsは開発者に原子性、一貫性、分離性、永続性(ACID)を保証した操作を一つか複数のテーブルに対して提供します。一つのAWSアカウントの単一リージョンで行います。アプリケーションからinsert、delete、updateを複数のアイテムに対して実施出来る事でビジネスロジックの操作を一回のリクエストで実行出来ます。DynamoDBは、複数のパーティショニングとテーブル間でトランザクションをサポートする唯一の非リレーショナルDBです。
TransacstionsはDynamoDBを利用してより広いワークロードに対してエンタープライズレベルでのbenefitとスケール、パフォーマンスをもたらします。多くのユースケースではすぐに簡単にtransactionsを利用することが可能です。例えば
- 金融取引
- 商品の受注から決済までの管理
- マルチプレイヤーでの操作を提供するゲーム
- 複数のコンポーネントによる操作を行うシステム
2つ目にDynamoDBのオペレーションでどうtransactionsを扱うのか紹介します。
- TransactWriteItems 書き込みを含む操作で利用します。一つか複数のPutItem、UpdateItem、そしてDeleteItemオペレーションをサポートします。TransactWriteItemsは指定した前提条件にマッチするかをチェックしてから更新することも可能です。これらの条件には書き込みセット内で同一Itemや異なるItemが含まれる場合があります。いずれかの条件が満たされない場合トランザクションはリジェクトされ失敗します。
- TransactGetItems 読み込みを含む操作で利用します。一つか複数のGetItemオペレーションをサポートします。もしTransactGetItemsリクエストで対象となっているItemがTransactWriteItemsで書き込まれている最中は読み込みトランザクションはキャンセルされます。書き込みトランザクション処理前の値は取得可能なので通常の読み込み操作は可能です。
これらのトランザクションはユニークな10個のItemと最大4MBのデータ、条件付き書き込みがサポートされます。
この機能を利用してDynamoDBは、さまざまなアプリケーション要件を満たす複数の読み取りと書き込みのオプションを提供し、複雑なデータ駆動型ビジネスロジックを実装する開発者に大きな柔軟性を提供します。
- 3種類の読み込みオプション – 結果整合性の読み込み、強力な整合性のある読み込み、そしてトランザクションによる読み込み
- 2種類の書き込みオプション – 通常書き込みとトランザクションによる書き込み
たとえば、仮想コインでアイテムを購入できるゲームを構築しているとします。
- player tableでは、各playerは多数のコインと購入したアイテムの在庫を持っています。
- itemsテーブルでは、各アイテムに価格が設定され、boolean値で使用可能(または使用不可)としてマークされます。
ゲーム内で商品を購入するフローの場合にアトミックトランザクション処理を実装出来ます。
- 始めに商品があるかを確認し、プレイヤーに必要な残高があるか確認する
- これらの条件が満たされている場合、商品を在庫無しに変更し所有者をプレイヤーに変更
- 支払ったアイテムをプレイヤーの持ち物リストに追加する
JavaScriptを用いた例として、AWS SDK for JavaScript in Node.jsで例を見てみましょう。
data = await dynamoDb.transactWriteItems({
TransactItems: [
{
Update: {
TableName: 'items',
Key: { id: { S: itemId } },
ConditionExpression: 'available = :true',
UpdateExpression: 'set available = :false, ' +
'ownedBy = :player',
ExpressionAttributeValues: {
':true': { BOOL: true },
':false': { BOOL: false },
':player': { S: playerId }
}
}
},
{
Update: {
TableName: 'players',
Key: { id: { S: playerId } },
ConditionExpression: 'coins >= :price',
UpdateExpression: 'set coins = coins - :price, ' +
'inventory = list_append(inventory, :items)',
ExpressionAttributeValues: {
':items': { L: [{ S: itemId }] },
':price': { N: itemPrice.toString() }
}
}
}
]
}).promise();
Transactionsの使用について
トランザクションはデフォルトで全ての単一リージョンにあるDynamoDBでは有効、global tablesでは無効になっています。グローバルテーブルのトランザクションを有効にすることもできますが、リージョン間のレプリケーションは非同期で、最終的には一貫性が保たれます。他のリージョンへのレプリケーションには部分的に完了したトランザクションを観測することがあります。さらに、異なるリージョンの同じアイテムへの同時書き込みは、トランザクションによる分離が保証されていません。
Itemはトランザクション中にロックされません。DynamoDB transactionsはトランザクション分離レベルだとserializableになります。トランザクションの進行中にアイテムがトランザクション外で変更された場合、トランザクションはキャンセルされ、例外を発生させたアイテムまたはItemに関する詳細がスローされます。
AWSのIdentity and Access Management(IAM)ポリシーを作成する場合、TransactGetItemsおよびTransactWriteItemの新しい権限はありません。既存のDynamoDB UpdateItem、PutItem、DeleteItem、およびGetItemは、これらの操作をトランザクション内でも許可します。たとえば、IAMユーザーがPutItem権限のみを持つ場合、1つ以上のputでトランザクションを実行できますが、書き込みセットに削除を追加すると、DeleteItem権限がないため却下されます。
価格設定、監視、および可用性
DynamoDBテーブルのトランザクションを有効にするための追加コストはありません。トランザクションの一部である読み取りまたは書き込み操作のみの課金を行います。DynamoDBはトランザクション内の各Itemに対して2回の読み取りまたは書き込みを行います。1つはトランザクションを準備するためのもので、もう1つはトランザクションをコミットするものです。2回の読み取り/書き込み操作は、CloudWatchメトリックに表示されます。各トランザクションが読取りか書き込みを2回実行すると仮定して、コスト、容量、およびパフォーマンスの必要性を計画する必要があります。
DynamoDBトランザクションは、すべての商用リージョンで利用できます。
私はこの新機能が出せたことを本当に嬉しく思っています。もし何かあれば是非私に教えてください!
(翻訳者: Solutions Architect 成田) 元記事 : New – Amazon DynamoDB Transactions
developer document : https://docs.thinkwithwp.com/amazondynamodb/latest/developerguide/transactions.html