1

GAE for Java で実行され、アプリケーション エンジン Datastore と Objectify 4 を使用する Web アプリケーションがあります。

ユーザーが Web から複数のフィールドを含むフォームを送信すると、アプリケーションのロジックはこれらの値をデータストアに投稿し、データのリスト (これらの最後の値を含む) を読み取り、Web に戻り、送信された最後の変更を残りのデータ。ほとんどの場合、問題なく動作します。

ただし、場合によっては (実際にはほとんど発生しません)、新しい値は保存されますが、Web に戻ったときに Web に表示されません。しかし、エクスプローラーを更新するだけで(読み取りプロセスを更新するため)、数秒後に値が表示されます。最初からあるはずです。

私のローカル環境でテストしたところ、これは私にも数回発生、「保存」または「おそらく、プロセスが速すぎて、新しい値がまだ利用できなかったためです (これは私の意見です)。したがって、実際のデータストアでも同様のことが起こる可能性があると思います。

この問題を簡単な方法で回避する方法を知っていますか? (可能であれば、同期ブロックなどを回避します)

4

1 に答える 1

4

祖先クエリなしで高レプリケーションデータストアを使用した結果、結果整合性の問題が発生しているようです。強一貫性のためのデータの構造化から(強調が追加されました):

Google App Engineの高レプリケーションデータストア(HRD)は、複数のデータセンターにデータを同期的に保存することで、読み取りと書き込みの高可用性を提供します。ただし、書き込みがコミットされてからすべてのデータセンターに表示されるまでの遅延は、複数のエンティティグループにまたがるクエリ(祖先以外のクエリ)が結果整合性のある結果しか保証できないことを意味します。その結果、そのようなクエリの結果は、基になるデータへの最近の変更を反映できない場合があります

一貫性の高いクエリ結果を取得するには、結果を単一のエンティティグループに制限する祖先クエリを使用する必要があります。これが機能するのは、エンティティグループが一貫性とトランザクション性の単位であるためです。すべてのデータ操作はグループ全体に適用されます。祖先クエリは、エンティティグループ全体が最新になるまで結果を返しません。アプリケーションが特定のクエリで非常に一貫性のある結果に依存している場合は、データモデルを設計するときにこれを考慮する必要があります。このページでは、強一貫性をサポートするようにデータを構造化するためのベストプラクティスについて説明します。

そのドキュメントの祖先クエリを使用して書き込みを行う例を次に示します。

import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.DatastoreServiceFactory;
import com.google.appengine.api.datastore.Entity;

String guestbookName = req.getParameter("guestbookName");
Key guestbookKey = KeyFactory.createKey("Guestbook", guestbookName);
String content = req.getParameter("content");
Date date = new Date();

// Place greeting in same entity group as guestbook
Entity greeting = new Entity("Greeting", guestbookKey);
greeting.setProperty("user", user);
greeting.setProperty("date", date);
greeting.setProperty("content", content);

そして読んで:

import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.DatastoreServiceFactory;
import com.google.appengine.api.datastore.Entity;

DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();

Key guestbookKey = KeyFactory.createKey("Guestbook", guestbookName);
Query query = new Query("Greeting", guestbookKey)
                    .setAncestor(guestbookKey)
                    .addSort("date", Query.SortDirection.DESCENDING);

List<Entity> greetings = datastore.prepare(query)
                                  .asList(FetchOptions.Builder.withLimit(10));

祖先クエリを使用する際の警告については、ドキュメントで詳しく説明しています。

于 2013-01-23T20:18:35.377 に答える