我正在努力实现强大的一致性。让我们调用我的模型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 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()
可以保证强大的一致性,所以我不明白为什么有时候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)
首先检查你的日志,其中一个更新必须失败并出现错误,因为你的逻辑基本上是正确的。
同时仔细检查所有更新是否包含在交易中以避免比赛。 Cloud Datastore: ways to avoid race conditions
这种情况可能不是关于一致性问题,而是重写更新,请查看此链接以了解一些有趣的案例:
http://engineering.khanacademy.org/posts/transaction-safety.htm http://engineering.khanacademy.org/posts/user-write-lock.htm
答案 1 :(得分:1)
是否存在超过每个实体组写入限制的情况,即每秒更新一次?我认为这可能会破坏文档中提到的实体组的强一致性。