拡張機能を使用して DynamoDB Enhanced Client オペレーションをカスタマイズする - AWS SDK for Java 2.x

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

拡張機能を使用して DynamoDB Enhanced Client オペレーションをカスタマイズする

DynamoDB 拡張クライアント API は、マッピング操作以外の機能を提供するプラグイン拡張機能をサポートしています。拡張機能は、読み取りおよび書き込みオペレーション中に 2 つのフックメソッドを使用してデータを変更します。

  • beforeWrite() - 書き込みオペレーションが発生する前に変更します

  • afterRead() - 読み取りオペレーションの実行後にその結果を変更します。

一部のオペレーション (項目の更新など) は書き込みと読み取りの両方を実行するため、両方のフックメソッドが呼び出されます。

拡張機能のロード方法

拡張機能は、拡張クライアントビルダーで指定した順序でロードされます。1 つのエクステンションが以前のエクステンションによって変換された値に作用する可能性があるため、ロード順序は重要な場合があります。

デフォルトでは、拡張クライアントは 2 つの拡張機能をロードします。

拡張クライアントビルダーを使用してデフォルトの動作を上書きし、拡張機能をロードできます。デフォルトの拡張機能を使いたくない場合は、none を指定することもできます。

重要

独自の拡張機能をロードしても、拡張クライアントはデフォルトの拡張機能をロードしません。いずれかのデフォルトの拡張機能と同じ動作をさせたい場合は、拡張機能のリストに明示的に追加する必要があります。

次の例は、 にverifyChecksumExtensionちなんで という名前のカスタム拡張機能をロードする方法を示していますVersionedRecordExtension。この例では、AtomicCounterExtension はロードされていません。

DynamoDbEnhancedClientExtension versionedRecordExtension = VersionedRecordExtension.builder().build(); DynamoDbEnhancedClient enhancedClient = DynamoDbEnhancedClient.builder() .dynamoDbClient(dynamoDbClient) .extensions(versionedRecordExtension, verifyChecksumExtension) .build();

利用可能な拡張機能の詳細と設定

以下のセクションでは、 SDK で使用可能な各拡張機能に関する詳細情報を提供します。

を使用して楽観的ロックを実装する VersionedRecordExtension

VersionedRecordExtension 拡張機能は、項目がデータベースに書き込まれるときに項目バージョン番号を増やして追跡することで、楽観的なロックを提供します。実際の永続項目のバージョン番号がアプリケーションが最後に読み取った値と一致しない場合、書き込みが失敗するすべての書き込みに条件が追加されます。

設定

アイテムのバージョン番号を追跡するために使用する属性を指定するには、テーブルスキーマの数値属性にタグを付けます。

次のスニペットでは、version 属性がアイテムのバージョン番号を保持するように指定しています。

@DynamoDbVersionAttribute public Integer getVersion() {...}; public void setVersion(Integer version) {...};

これと同等の静的テーブルスキーマのアプローチは、次のスニペットで示されます。

.addAttribute(Integer.class, a -> a.name("version") .getter(Customer::getVersion) .setter(Customer::setVersion) // Apply the 'version' tag to the attribute. .tags(VersionedRecordExtension.AttributeTags.versionAttribute())

仕組み

を使用したオプティミスティックロックVersionedRecordExtensionは、これらの DynamoDbEnhancedClientおよび DynamoDbTableメソッドに次の影響を与えます。

putItem

新しい項目には、初期バージョン値 0 が割り当てられます。これは で設定できます@DynamoDbVersionAttribute(startAt = X)

updateItem

項目を取得して 1 つ以上のプロパティを更新し、変更を保存しようとすると、クライアント側とサーバー側のバージョン番号が一致する場合にのみオペレーションが成功します。

成功すると、バージョン番号は自動的に 1 ずつ増加します。これは で設定できます@DynamoDbVersionAttribute(incrementBy = X)

deleteItem

DynamoDbVersionAttribute 注釈は効果がありません。項目を削除するときは、条件式を手動で追加する必要があります。

次の例では、条件式を追加して、削除された項目が読み取られた項目であることを確認します。次の例は、 で注釈が付けられた Bean の 属性recordVersionです@DynamoDbVersionAttribute

// 1. Read the item and get its current version. Customer item = customerTable.getItem(Key.builder().partitionValue("someId").build()); // `recordVersion` is the bean's attribute that is annotated with `@DynamoDbVersionAttribute`. AttributeValue currentVersion = item.getRecordVersion(); // 2. Create conditional delete with the `currentVersion` value. DeleteItemEnhancedRequest deleteItemRequest = DeleteItemEnhancedRequest.builder() .key(KEY) .conditionExpression(Expression.builder() .expression("recordVersion = :current_version_value") .putExpressionValue(":current_version_value", currentVersion) .build()).build(); customerTable.deleteItem(deleteItemRequest);
transactWriteItems
  • addPutItem: このメソッドの動作は と同じですputItem

  • addUpdateItem: このメソッドの動作は と同じですupdateItem

  • addDeleteItem: このメソッドの動作は と同じですdeleteItem

batchWriteItem
  • addPutItem: このメソッドの動作は と同じですputItem

  • addDeleteItem: このメソッドの動作は と同じですdeleteItem

注記

DynamoDB グローバルテーブルは、同時更新間の「最後のライター獲得」調整を使用します。DynamoDB は最後のライターを決定するために最善を尽くします。グローバルテーブルを使用する場合、この「最後のライター獲得」ポリシーは、すべてのレプリカが最終的に DynamoDB によって決定された最後の書き込みに基づいて収束するため、ロック戦略が期待どおりに機能しない可能性があることを意味します。

を無効にする方法

楽観的ロックを無効にするには、 @DynamoDbVersionAttribute注釈を使用しないでください。

を使用してカウンターを実装する AtomicCounterExtension

AtomicCounterExtension 拡張機能は、レコードがデータベースに書き込まれるたびに、タグ付けされた数値属性を増分します。開始値と増分値を指定できます。値を指定しない場合、開始値は 0 に設定され、属性の値は 1 ずつ増加します。

設定

どの属性がカウンターかを指定するには、テーブルスキーマのタイプ Long の属性にタグを付けます。

次のスニペットは、counter 属性のデフォルトの開始値と増分値の使用方法を示しています。

@DynamoDbAtomicCounter public Long getCounter() {...}; public void setCounter(Long counter) {...};

次のスニペットは、静的テーブルスキーマのアプローチを示しています。アトミックカウンタ拡張機能は、開始値を 10 に設定し、レコードが書き込まれるたびに値を 5 ずつ増やします。

.addAttribute(Integer.class, a -> a.name("counter") .getter(Customer::getCounter) .setter(Customer::setCounter) // Apply the 'atomicCounter' tag to the attribute with start and increment values. .tags(StaticAttributeTags.atomicCounter(10L, 5L))

でタイムスタンプを追加する AutoGeneratedTimestampRecordExtension

AutoGeneratedTimestampRecordExtension 拡張機能は、項目がデータベースに正常に書き込まれるたびに、 タイプのタグ付けされた属性を現在のタイムスタンプInstantで自動的に更新します。このエクステンションはデフォルトではロードされません。

設定

現在のタイムスタンプで更新する属性を指定するには、テーブルスキーマの Instant 属性にタグを付けます。

lastUpdate 属性は、次のスニペットの拡張機能の動作のターゲットです。属性は Instant タイプでなければならないという要件に注意してください。

@DynamoDbAutoGeneratedTimestampAttribute public Instant getLastUpdate() {...} public void setLastUpdate(Instant lastUpdate) {...}

これと同等の静的テーブルスキーマのアプローチは、次のスニペットで示されます。

.addAttribute(Instant.class, a -> a.name("lastUpdate") .getter(Customer::getLastUpdate) .setter(Customer::setLastUpdate) // Applying the 'autoGeneratedTimestamp' tag to the attribute. .tags(AutoGeneratedTimestampRecordExtension.AttributeTags.autoGeneratedTimestampAttribute())

AutoGeneratedUuidExtension を使用して UUID を生成する

AutoGeneratedUuidExtension 拡張機能は、新しいレコードがデータベースに書き込まれるときに、属性の一意の UUID (Universally Unique Identifier) を生成します。Java JDK UUID.randomUUID() メソッドを使用し、タイプ の属性に適用されますjava.lang.String。このエクステンションはデフォルトではロードされません。

設定

uniqueId 属性は、次のスニペットの拡張機能の動作のターゲットです。

@AutoGeneratedUuidExtension public String getUniqueId() {...} public void setUniqueId(String uniqueId) {...}

これと同等の静的テーブルスキーマのアプローチは、次のスニペットで示されます。

.addAttribute(String.class, a -> a.name("uniqueId") .getter(Customer::getUniqueId) .setter(Customer::setUniqueId) // Applying the 'autoGeneratedUuid' tag to the attribute. .tags(AutoGeneratedUuidExtension.AttributeTags.autoGeneratedUuidAttribute())

拡張機能が putItemメソッドに対してのみ UUID に入力されるようにし、 updateItemメソッドに対して入力しないようにするには、次のスニペットに示すように、更新動作注釈を追加します。

@AutoGeneratedUuidExtension @DynamoDbUpdateBehavior(UpdateBehavior.WRITE_IF_NOT_EXISTS) public String getUniqueId() {...} public void setUniqueId(String uniqueId) {...}

静的テーブルスキーマアプローチを使用する場合は、次の同等のコードを使用します。

.addAttribute(String.class, a -> a.name("uniqueId") .getter(Customer::getUniqueId) .setter(Customer::setUniqueId) // Applying the 'autoGeneratedUuid' tag to the attribute. .tags(AutoGeneratedUuidExtension.AttributeTags.autoGeneratedUuidAttribute(), StaticAttributeTags.updateBehavior(UpdateBehavior.WRITE_IF_NOT_EXISTS))