4

Google Cloud Datastoreで一貫したread - > update - > set操作を実行するためにエンティティ(user(amount_earned)など)をロックするための推奨方法。Google Cloudデータストアでget-update-set操作を実行するエンティティをロックする

memcacheを使用すると、通常、オブジェクトを変更するプロセス/スレッドのみが存在することを確認するために、memcache.add(lock_key)を実行します。

memcacheのaddはアトミックであり、falseが返されるため、以前にkeyが追加されなかった場合、memcacheを使用して「ロック」をシミュレートするのは簡単です。

Google Cloudデータストアで同様のロックセマンティクスをシミュレートするにはどうすればよいですか。

理想的

with gcp.lock(lock_key)as key: 
    user.get(user_id) # read 
    user.update(amount) # update 
    user.set() # save 

# Release the lock, so that other processes can now updated user (identified by user_id) object 

答えて

4

あなたはおそらくTransactionsOptimistic Locking戦略を使用することができます。

Userエンティティを更新する例を考えてみましょう。オプティミスティックロックを使用するには、特別なプロパティ(エンティティバージョンなど)を使用する必要があります。バージョンフィールドは、更新ごとに1ずつ増加します。エンティティを更新する手順:

  1. エンティティ
  2. をロードするには、[ユーザーエンティティの更新を可能にするUIを持っていると仮定します。エンティティを編集モードで画面に表示します。
  3. エンドユーザーレビューは/
  4. エンドユーザーが[保存]をクリックしたエンティティへの変更を行う
  5. 今、トランザクションが
  6. ロードエンティティのキ​​ーが
  7. が新たにロードされたエンティティとエンティティのバージョンを比較し
  8. 使用してUserエンティティを開始以前にUIにロードされている
  9. バージョンが一致する場合、他の誰もエンティティを更新していないので、エンティティを更新してトランザクションをコミットします。更新/コミット中にバージョン番号をインクリメントしてください。バージョンが一致しない場合、他の誰かがエンティティを変更しました。エンティティを更新せず、トランザクションをロールバックします。適切な処置をとってください。たとえば、ユーザーにメッセージを表示し、最新のエンティティを確認してさらに変更を加えることができます。
+0

これは素晴らしいです!しかし、[7]と[8]の間には依然として競争条件が存在する可能性があります。 ステップ[7]と[8]を同時に実行するスレッドは複数存在する可能性がありますか? – user462455

+1

はい、それはトランザクションによって注意が払われます。コミットする最初のトランザクションが勝ち、2番目のトランザクションは失敗します。それは私が投稿したリンクの文書です。 **トランザクション内では、直列化可能な分離が強制されます。つまり、このトランザクションによって読み取られたり変更されたデータを他のトランザクションが同時に変更することはできません。 ** –

+0

エンティティを同時に更新できるトランザクションは2つありません。クラウドデータストアは、取引がシリアル化されていることを確認します。したがって、トランザクションを使用せずに起こっている更新操作がある場合にのみ、アプリケーションはオプティミスティックロックを実装する必要があります。 – user462455

関連する問題