2011-09-21 182 views
0

在我的Java應用程序中,有時我的用戶做了一些需要數據存儲區寫入的工作,但我不想讓用戶在數據存儲區寫入時等待。我想在數據存儲在後臺時立即向用戶返回響應。異步寫入GAE數據存儲區

這似乎很清楚,我可以通過使用GAE任務隊列來排隊存儲數據。但是我也看到有一個Async數據存儲API,它看起來比處理任務隊列要容易得多。

我可以直接調用AsyncDatastoreService.put()然後從我的servlet中返回嗎?該API將存儲我的數據而不讓我的用戶等待?

回答

3

我認爲你是對的,異步調用似乎更容易。但是,AsyncDatastore的docs提到一個需要注意的警告:

注意:除非調用get()方法,否則不引發異常。調用此方法可以驗證異步操作是否成功。

該筆記中的「get」被異步調用返回的Future對象調用。如果你只是從你的servlet中返回而沒有調用Future對象,你可能無法確定你的put()是否工作。

對於排隊的任務,您可以更明確地處理錯誤情況,或者只依靠自動重試。如果你想要排隊的是數據存儲庫,你應該能夠創建(或者查找)一個工具類,爲你完成大部分的工作。

0

如果你需要的只是讓用戶有一個響應接口,而在數據庫後面的東西攪動,你所要做的就是在客戶端進行一次異步調用,也就是做一些發送數據庫的ajax寫入請求,更改用戶顯示,然後在ajax請求回調時更新視圖,無論您希望如何。

您可以輕鬆地爲您的GAE項目添加GWT支持(通過eclipse插件或maven gae插件),並讓您的生活中的時間做到異步的東西。

+0

我同意使用AJAX是一個好主意。在我的情況下,用戶正在做一個完整的頁面表單POST,所以它不適合。 –

+0

是的,但是看看,在他提交表單和數據庫完成處理之間的很長一段時間後(以及帖子響應),你現在顯示什麼?只是讓異步提交(jQuery和原型都提供設施),立即顯示的東西,並更新顯示(如頁眉或什麼)與數據庫提交的狀態一旦回調返回 –

1

不幸的是,這裏沒有任何真正好的解決方案。你可以排隊一個任務,但有幾大問題,這:

  • 任務有效載荷大小限制,以及大小比實體大小限制較小。
  • 將記錄寫入數據存儲實際上是相當快的,在掛鐘時間。成本的一個重要部分也是序列化數據,無論如何您必須將其添加到任務隊列中。
  • 通過使用任務隊列,您可以創建更多最終一致性 - 用戶可能會回來並且看不到應用的更改,因爲該任務尚未執行。您也可能會介紹交易問題 - 您如何處理併發更新?
  • 如果出現問題,可能需要花費任意長的時間來應用用戶的更新。在這種情況下,簡單地向用戶返回錯誤可能會更好。

我的建議是在可能的情況下使用異步API,但要始終直接寫入數據存儲區。請注意,您需要等待所有優秀的API調用,正如Peter指出的那樣,或者您不知道它們是否失敗 - 如果您不等待它們,那麼應用程序服務器會在向用戶返回響應之前。

+0

這是一個有趣的您在回答結束時提到的珍聞。文檔似乎沒有提到如果您沒有明確地等待未完成的呼叫會發生什麼。您是說應用服務器會跟蹤您的哪些呼叫仍然未完成,並在向用戶返回響應之前自動阻止它們?這可能是文檔的一個很好的補充。 –

+0

@Peter這是正確的。事實上,在開發服務器中,除非您專門等待,否則您的調用可能甚至不會執行。 –