データストアトランザクションの制限
-
10-07-2019 - |
質問
Googleアプリアプリケーションでは、ユーザーが多数の契約を購入するたびに、これらのイベントが実行されます(わかりやすくするために簡略化されています):
- user.cashが減少しました
- user.contractsは数だけ増加します
- contracts.current_priceが更新されました。
- market.no_of_transactionsは1増加します。
rdmsでは、これらは同じトランザクション内に配置されます。 Googleデータストアでは、複数のモデルのエンティティを同じトランザクションに含めることはできません。
この問題に対する正しいアプローチは何ですか?書き込みが失敗した場合、前のすべての書き込みがロールバックされるようにするにはどうすればよいですか?
編集:エンティティグループを見逃しました。今、私はそれらがどのように使用されるかに関するいくつかのさらなる情報に感謝します。明確にするもう1つのポイントは、Googleが「エンティティグループをトランザクションに必要な場合にのみ使用する」ということです。エンティティ間の他の関係については、ReferencePropertyプロパティとキー値を使用します。これらはクエリで使用できます"。参照プロパティ(クエリを実行する必要があるため)と親子関係(トランザクションの場合)の両方を定義する必要があるということですか?
編集2:最後に、エンティティが2つの親の間にn対nの関係を確立するために作成されている場合、エンティティの2つの親をどのように定義しますか?
解決
徹底的な調査の結果、単一のエンティティグループの制限に対する解決策を提供する分散トランザクションレイヤーが、一部のGoogleユーザーの助けを借りてユーザーランドで開発されていることがわかりました。しかし、これまでのところ、リリースされておらず、javaでのみ利用可能です。
他のヒント
エンティティグループの良い経験則は、エンティティグループが 単一ユーザーの価値のサイズ データ以下。
擬似ルートエンティティを作成し、この下にすべてを配置できます。次に、トランザクションですべてを実行します。
shanyu、1つのトランザクションで任意の数のエンティティグループを操作できる分散トランザクションレイヤーについて説明しました。それは実際に リリースされましたが、あまり宣伝されていません。それはダニエル・ウィルカーソンとエリック・アームブラストによって設計され、書かれました。ダンは、この講演で説明しています。
nick johnsonも説明しています 実行方法"転送"エンティティグループ間で操作を入力します、説明と同様です。タピオカオームほど一般的な目的ではありませんが、よりシンプルで軽量です。
関連する組み込み機能、トランザクションタスク、データストアトランザクション内のキューにタスクを追加できます。これにより、トランザクションが正常にコミットされた場合にのみタスクが追加されます。そのタスクは、別のエンティティグループでのトランザクションを含む、より多くのデータストア操作を実行できます。ダンとエリックのソリューションほど強力ではありませんが、エンティティグループ間で最終的な一貫性を保証します。これは、余分なオーバーヘッドなしで多くのユースケースに十分適しています。
質問への回答:1)参照プロパティと親/子関係(つまり、エンティティグループ)の両方を使用する必要はありません。このガイドラインは、エンティティグループごとに書き込みがシリアル化されるため、エンティティグループがデータストアの書き込みスループットを制限することを意味します。祖先クエリのためだけにデータをエンティティグループに構造化することを検討している場合は、そのことに注意する必要があります。
2)エンティティは複数の親を持つことはできません。多対多の関係をモデル化する場合は、通常、参照プロパティ(つまりキー)のListPropertyを使用する必要があります。 この記事およびこの講演をご覧ください。