2013-01-23 27 views
1

我有一個Web應用程序上運行GAE Java和使用App Engine數據存儲和物化4.沒有新的內容使用GAE

當用戶提交表單從幾個領域提交表格後顯示在Web應用程序Web應用程序的邏輯應該將這些值發佈到數據存儲中,讀取數據列表(包含這些最後的值)並返回到Web,以顯示與其餘數據一起提交的這些最後更改。大多數時候它工作正常。

但是,有時候(它真的發生了很少的時間),新的值保存,但返回到網頁的時候,他們不會出現在網頁上。但只是刷新資源管理器(如此刷新閱讀過程)幾秒鐘後,值有,因爲他們應該從第一次。

測試在我的本地環境中,這發生在我身上的一些幾次爲好,我得到了一個錯誤說像用於模擬數據存儲的文本文件(稱爲是local_db.bin)期間,未正常關閉 「儲蓄」或「閱讀」過程,可能是因爲過程太快,新的價值尚未提供(這是我的看法)。所以我猜想在真實的數據存儲上會發生類似的情況。

你知道如何以簡單的方式避免這個問題嗎? (如果可能,避免同步塊等)

回答

4

這聽起來像是由於在沒有祖先查詢的情況下使用高複製數據存儲而導致出現eventual consistency問題。從Structuring Data for Strong Consistency(強調):

谷歌App Engine的高複製資料儲存庫(HRD)提供高可用性 爲您讀取和存儲數據在多個數據中心同步寫入 。然而,從提交寫入的時間延遲到它在所有數據中心中變得可見爲止,意味着跨多個實體組(非祖先查詢)的查詢只能保證最終一致的結果。因此, 的結果此類查詢有時可能無法反映最近對 基礎數據所做的更改。

要獲得強烈一致的查詢結果,您需要使用 祖先查詢將結果限制爲單個實體組。這個 的作品,因爲實體組是一致的單位,以及 事務性。所有數據操作都適用於整個組; 祖先查詢將不會返回其結果,直到整個實體組 組是最新的。如果您的應用程序依賴於針對某些查詢的強烈一致的 結果,則在設計數據模型時可能需要考慮此問題 。本頁討論最佳的 結構化數據支持強一致性的做法。

下面是一個使用祖先查詢從該文件寫入的例子:更詳細的文件中討論

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)); 

注意事項使用祖先查詢:

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); 

和閱讀。

+0

感謝您的回答,並把我放在正確的軌道上。我忘了提及我正在與Objectify 4合作,並且查看它的文檔,它也經歷了您指出的最終一致性問題。在我的情況下,我可以通過[事務繼承](http://code.google.com/p/objectify-appengine/wiki/Transactions)解決我的問題。 – Joar