5


2

Google App Engineで、データベーストランザクションを実装するにはどうすればよいですか?

アプリエンジンでDBトランザクションを処理する方法は、異なるエンティティに同じ「親」(エンティティグループ)を与え、「db.run_in_transaction」を使用することです。

ただし、2つのエンティティに同じ親を与えることはできません。 DB更新がトランザクションで発生することを確認するにはどうすればよいですか?

技術的な解決策はありますか? そうでない場合、適用できるパターンはありますか?

注:Pythonを使用しています。

5 Answer


5


エンティティが同じグループに属している限り、これは問題ではありません。 docsから:

_ トランザクション内のすべてのデータストア操作は、同じエンティティグループ内のエンティティで操作する必要があります。 これには、祖先によるエンティティのクエリ、キーによるエンティティの取得、エンティティの更新、およびエンティティの削除が含まれます。 各ルートエンティティは個別のエンティティグループに属しているため、1つのトランザクションで複数のルートエンティティを作成または操作することはできません。 エンティティグループの説明については、「キーとエンティティグループ」を参照してください。 _

App Engineでのトランザクション分離に関する素晴らしい記事もあります。

編集:同じトランザクションで異なる親を持つエンティティを更新する必要がある場合、自分で行った変更をシリアル化し、例外が発生した場合は手動でロールバックする方法を実装する必要があります。


3


エンティティ間のグループトランザクションが必要な場合は、自分で実装するか、ライブラリがトランザクションを実行するのを待つ必要があります。 「銀行振込」の場合にエンティティ間グループトランザクションを実装する方法については、少し前にhttp://blog.notdot.net/2009/9/Distributed-Transactions-on-App-Engine [記事]を書きました。ユースケースにも適用される場合があります。


2


AppEngineデータストア内のトランザクションは、SQLデータベースで使用されるトランザクションとは異なる動作をします。 一つには、トランザクションは実際に操作しているエンティティをロックしません。

これについて詳しくは、http://code.google.com/appengine/articles/transaction_isolation.html [App Engineの翻訳隔離]の記事で説明しています。

このため、トランザクションについて異なる考え方をする必要があります-トランザクションを使用するほとんどの場合、それは不要であるか、または目的を達成できないことがわかります。

エンティティグループとデータストアモデルの詳細については、http://code.google.com/appengine/articles/storage_breakdown.html [エンティティとインデックスの保存方法]をご覧ください。

http://code.google.com/appengine/articles/handling_datastore_errors.html [データストアエラーの処理]では、トランザクションがコミットされない原因となる問題とその対処方法について説明しています。


2


可能性の1つは、前述のように独自のトランザクション処理を実装することです。 これを行うことを考えている場合は、この問題に関する以前の研究を調べるのに時間をかける価値があります。

ダンウィルカーソンは、Google IOでも講演を行いました。 講演のビデオを見つけることができるはずです。


0


エリック・アームブラストは、前述のダニエル・ウィルカーソンの分散トランザクション設計をJavaで実装しました:http://code.google.com/p/tapioca-orm/