1

これが正しいという確認だけが必要です。たとえばX、フィールドを持つエンティティがxあり、リクエストが送信されたときに実行したい場合X.x++。ちょうど使用する場合X = ofy().load().type(X.class).id(xId).get()は、いくつかの計算を行い、後で計算しX.x++て保存します。計算中に別のリクエストが投稿されると、望ましくない動作が発生します。X代わりに、これをすべてトランザクションで行う場合、2 番目のリクエストは完了するまでアクセスできません。

そうですか?

質問が少しわかりにくい場合は申し訳ありません。

ありがとう、ダン

4

2 に答える 2

2

はい、あなたはそれを正しく理解しましたが、トランザクションを使用するときは、勝利を完了する最初のものを覚えておいて、残りは失敗します。それらがどのように機能するかについては、@Peter Knegoの回答もご覧ください。

ただし、読み取りに失敗した場合でも、2 番目の要求について心配する必要はありません。次の 2 つのオプションがあります。

  1. 再試行を強制する
  2. トランザクションで結果整合性を使用する

再試行に関する限り:

トランザクション関数は、望ましくない副作用なしに安全に複数回呼び出すことができます。これが不可能な場合は、retries=0 を設定できますが、競合が最初に発生したときにトランザクションが失敗することを知っておいてください。

例:

@db.transactional(retries=10)

結果整合性に関する限り:

結果整合性を要求する読み取りポリシーを指定することで、この保護を無効にすることができます。結果整合性のあるエンティティの読み取りを使用すると、アプリは、適用するコミットされた変更がまだあるかどうかに関係なく、読み取られているエンティティの現在の既知の状態を取得します。結果整合性の祖先クエリでは、クエリに使用されるインデックスは、インデックスがディスクから読み取られる時間と一貫性があります。つまり、結果整合性読み取りポリシーにより、取得とクエリが現在のトランザクションの一部ではないかのように動作します。結果を返す前に、コミットされた変更が書き込まれるのを待つ必要がないため、場合によっては、この方が高速になることがあります。

例:

@db.transactional()
def test():
    game_version = db.get(
        db.Key.from_path('GameVersion', 1),
        read_policy=db.EVENTUAL_CONSISTENCY)
于 2012-12-24T11:33:27.770 に答える