【发布时间】:2016-08-25 08:48:56
【问题描述】:
我正在努力实现强一致性。让我们叫我的模型PVPPlayer:
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 网址:
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() 保证了强一致性,所以我不明白为什么有时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 !!!`
【问题讨论】:
-
你的#2函数是否也用
@ndb.transactional装饰?另外,我认为#1 中的update_points函数名确实是update_points,对吧? -
>你的#2 函数是否也用@ndb.transactional 装饰?我尝试为#2 添加@ndb.transactional 但没关系-它仍然不时给我陈旧的数据>#1 中的update_points 函数名称确实是update_points,对吗?绝对
-
抱歉,我的意思是
some_func是update_points? :) -
你可以调用 some_func "commit" 函数。它更新了 PVPPlayer 点并保存了一些其他模型,例如 PVPMatch(some_func 最多可以在 3 个实体组中运行),但我在这个请求中只更新了一次 PVPPlayer 模型。
标签: python google-app-engine eventual-consistency