7

Windows Azure テーブル ストレージ サービスで条件付き挿入を行うことはできますか?

基本的に、私がやりたいことは、最後に調べてからそのパーティションで何も変更されていない場合に限り、Table Storage Service のパーティションに新しい行/エンティティを挿入することです。

ご参考までに、私はイベント ソーシングを念頭に置いていますが、質問はそれよりも一般的なものだと思います。

基本的に、パーティションの一部または全体を読み取り、データの内容に基づいて決定を下したいと考えています。データがロードされてからパーティション内で何も変更されていないことを確認するために、挿入は通常のオプティミスティック コンカレンシーのように動作する必要があります。挿入は、パーティション内で何も変更されていない場合 (行が追加、更新、または削除されていない場合) にのみ成功する必要があります。

通常、REST サービスでは、ETag を使用して同時実行を制御することを期待しますが、私が知る限り、パーティション用の ETag はありません。

私が思いつく最善の解決策は、タイムスタンプ/ETag を含むテーブル内の各パーティションに対して単一の行/エンティティを維持し、すべての挿入を、挿入とこの ' の条件付き更新で構成されるバッチの一部にすることです。タイムスタンプエンティティ」. ただし、これは少し面倒で脆いように思えます。

これは Azure Table Storage Service で可能ですか?

4

2 に答える 2

3

千フィートからの眺め

ちょっとした話をあなたと共有できますか...

昔々、誰かが特定のコマンドに応答して (ドメイン駆動設計の名声から) 集約のイベントを保持したいと考えていました。この人物は、集計が 1 回だけ作成されるようにし、あらゆる形式の楽観的同時実行を検出できるようにしたいと考えていました。

最初の問題 (集約は 1 回だけ作成する必要がある) に取り組むために、彼は重複した集約 (より正確にはその主キー) が検出されたときにスローするトランザクション メディアへの挿入を行いました。彼が挿入したのは、主キーとしての集約識別子と変更セットの一意の識別子でした。コマンドの処理中に集約によって生成されたイベントのコレクションは、ここでの変更セットが意味するものです。誰かまたは他の何かが彼を打ち負かした場合、彼はすでに作成された集計を考慮し、そのままにしておくでしょう。変更セットは、彼が選択したメディアに事前に保存されます。このメディアがしなければならない唯一の約束は、求められたときに保存されたものをそのまま返すことです. 変更セットの保存に失敗すると、操作全体の失敗と見なされます。

2 番目の問題 (集計のさらなるライフサイクルにおける楽観的同時実行の検出) に取り組むために、彼はさらに別の変更セットを作成した後、トランザクション メディアの集計レコードを更新します (背後で誰も更新していない場合のみ)。つまり、コマンドを実行する直前に最後に読んだものと比較します)。そのようなことが起こった場合、取引媒体は彼に通知します。これにより、彼は操作全体を再開し、集約 (またはその変更セット) を再読み取りして、今度はコマンドを成功させます。

もちろん、彼は書く問題を解いたので、読む問題も出てきました。履歴を構成する集約のすべての変更セットを読み取るにはどうすればよいでしょうか? 結局、彼はそのトランザクション メディアの集約識別子に関連付けられた、最後にコミットされた変更セットしか持っていませんでした。そこで彼は、各変更セットの一部としていくつかのメタデータを埋め込むことにしました。変更セットの一部として持つことはそれほど珍しいことではないメタデータの中には、前回最後にコミットされた変更セットの識別子があります。このようにして、いわばリンクされたリストのように、集約のチェンジセットの「一線を画する」ことができました。

さらに、変更セットのメタデータの一部としてコマンド メッセージ識別子を保存することもできました。このようにして、変更セットを読み取るときに、集約に対して実行しようとしているコマンドがすでにその履歴の一部であるかどうかを事前に知ることができました。

終わりよければ全てよし ...

PS
1. トランザクション メディアとチェンジセット ストレージ メディアは同じにすることができます 。
2. チェンジセット識別子はコマンド識別子であってはなりません

ストレージ、私は AWS DynamoDB と AWS S3 を使用して上記の話をうまく実装しました。

于 2012-01-31T19:09:39.237 に答える
2

AggregateId/AggregateVersion に基づいて作成された「PartitionKey/RowKey」に各イベントを格納するのはどうですか?ここで、AggregateVersion は、集計が既に持っているイベントの数に基づく連番です。

これは非常に決定論的であるため、集計に新しいイベントを追加するときは、最新バージョンを使用していることを確認してください。そうしないと、そのパーティションの行が既に存在するというエラーが表示されます。この時点で、現在の操作をドロップして再試行するか、集計に対する新しい更新が実行した操作と競合しない場合は、とにかく操作をマージできるかどうかを判断してみてください。

于 2012-01-31T19:45:52.940 に答える