我一直在使用App Engine幾年,似乎一次又一次與HDR一起彈出的問題是,當您在一個屏幕上更新數據時,您將有時如果只讀請求是在更新的一兩秒內完成的,則會在該屏幕的只讀版本上檢索舊數據。我知道這已被討論here和here。我知道問題是什麼,但我想知道適當的解決方案可能是什麼?這是一個我可以在哪裏陳舊數據的例子。谷歌App Engine保存並避免獲取舊數據
假設您構建購物清單應用程序。
Entity 1: ShoppingList
Entity 2: ShoppingListItem
ShoppingList實體上有一個字段,用於保存列表中的總量項目。第二個實體是您的ShoppingListItem。當您添加或刪除ShoppingListItem時,您需要更新ShoppingList上的總數。你有兩種方法來更新總數。
- 查詢數據庫並統計ShoppingListItem表中的項目數。
- 自動遞增緩存的總字段+/- 1,而不需要統計數據庫。
有了這兩種解決方案,您最終會得到過時的數據。 #1可能已過時,因爲添加/刪除的原始保存可能尚未傳播。因此查詢會錯過新記錄。當您快速連續添加或移除多個項目時,#2將會有過時的數據。總數更新爲保存1但保存2,保存1可能仍在傳播,對於保存2的ShoppingList總計查詢仍將反映保存前的原始狀態1.
所以我的問題是,什麼是正確的方法來解決這個問題對我來說,似乎你有兩種選擇:
- 使用緩存總數時總是使用memcached實體。保存不會清除內存緩存,而是直接將更新後的實體注入到內存中。這使memcache保持最新狀態。這當然意味着不會觸及memcache的查詢(例如獲取所有ShoppingList實體的列表)可能仍會返回陳舊的數據。但至少當所有的保存完成後,數據庫中的緩存總數將是正確的。
- 處理您將要陳舊的數據,然後找出將來某個時間清理它的方法。可以安排一個TaskQueue重新查詢ShoppingList並在10-30秒內更新總數或者計劃一個每30秒運行一次的Cron Job並查找所有已更新的ShoppingList實體。
我傾向於解決方案#1。思考?
感謝您的建議。不幸的是我不能使用實體組,因爲每秒寫入限制爲1。從文檔:「這種方法通過寫入每個留言簿的單個實體組來實現強大的一致性,但它也將留言簿的更改限制爲每秒不超過1次寫入(支持的實體組限制)」 – dirkoneill 2014-11-12 00:25:08