2016-08-25 54 views
0

我試圖實現強一致性。讓我們把我的模型PVPPlayerAppEngine實現強一致性

class PVPPlayer(ndb.Model): 
    points = ndb.IntegerProperty() 

爲模型中的每個關鍵是這樣創建的:

pvp_player = PVPPlayer(key=ndb.Key(Profile, "test_id", PVPPlayer, "test_id")) 

其中Profile是父模型:

class Profile(ndb.Model): 
    def build_key(cls, some_id): 
     return ndb.Key(cls, some_id) 

我有2個REST API URL:

1) update_points 
2) get_points 

在1)我做的:

# I use transaction because I have to update all the models in single batch 
@ndb.transactional(xg=True, retries=3) 
def some_func(points): 
    pvp_player = ndb.Key(Profile, "test_id", PVPPlayer, "test_id").get() 
    pvp_player.points += points 
    pvp_player.put() 
    # update other models here` 

在2)我做的:

pvp_player = ndb.Key(Profile, "test_id", PVPPlayer, "test_id").get() 
return pvp_player.points` 

我的流程是這樣的:

1) update_points() 
2) get_points() 
3) update_points() 
4) get_points()` 
... 

問題

使用get()保證強一致性o我不明白的是爲什麼有時候由於get_points()的結果,我得到的數據像陳舊的數據根本沒有更新。

POST get_points -> 0 
POST sleep 1-3 sec 
POST update_points -> 15 
POST sleep 1-3 sec 
POST get_points -> 15 
POST sleep 1-3 sec 
POST update_points -> 20 
POST sleep 1-3 sec 
POST get_points -> 15 !!!` 
+0

是您的#2功能,還裝飾有'@ndb .transactional'?另外,我認爲#1中的'update_points'函數名稱確實是'update_points',對嗎? –

+0

>你的#2功能是否也用@ ndb.transactional裝飾過? 我試圖爲#2添加@ ndb.transactional,但它並不重要 - 它仍然不時給我陳舊的數據 >#1中的update_points函數名稱確實是update_points,對不對? 絕對 –

+0

對不起,我的意思是'some_func'是'update_points'? :) –

回答

1

有你超過每實體組的寫入限制的情況下,即每秒更新?我認爲這可能會破壞文檔中提到的實體組的強大一致性。

+0

Physical player是唯一一個更新PVPPlayer模型的人。根據遊戲邏輯,有人同時執行2個update_points()請求的情況根本不會發生 –

+0

實際上更奇怪的是,有時兩個相繼的update_points()之間有15-20秒的間隔,但數據是仍然陳舊,所以它的行爲完全一致,但我不明白爲什麼 –

2

首先檢查您的日誌,其中一個更新必須失敗,錯誤,因爲您的邏輯基本上是正確的。

同時仔細檢查您的所有更新是否包含在交易中以避免競爭。 Cloud Datastore: ways to avoid race conditions


這種情況很可能不是一致性問題,但跺腳更新,結帳這個鏈接一些有趣的案例:

http://engineering.khanacademy.org/posts/transaction-safety.htm http://engineering.khanacademy.org/posts/user-write-lock.htm

+0

我只是明白,我的一個請求與update_points()同時更新我的​​父模型(即配置文件)。這看起來像問題 –

+0

我是否必須分配不同的父鍵來避免此問題? –

+0

共享包括父項的父項的所有內容都位於同一個實體組中。 –