AppEngine实现强一致性

AppEngine achieving strong consistency

我正在努力实现强一致性。让我们称我的模型为 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 !!!`

是否存在超出每个实体组写入限制的情况,即每秒更新一次?我认为这可能会破坏文档中提到的实体组的强一致性。

首先检查你的日志,肯定有一个更新失败并出错,因为你的逻辑基本上是正确的。

还要仔细检查所有更新都包含在事务中以避免竞争。


这个案例可能不是关于一致性问题,而是关于更新,检查这个链接以了解一些有趣的案例:

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