云数据存储:避免竞争条件的方法

时间:2016-08-15 13:12:17

标签: google-app-engine google-cloud-datastore gae-python27

我有很多操作同类实体的视图:

def view1(request, key):
    user = ndb.Key(urlsafe=key).get()
    user.x = 1
    user.put()
    ...

def view2(request, key):
    user = ndb.Key(urlsafe=key).get()
    user.y = 2
    user.put()
    ...

显然,由于可能的竞争条件(最后的胜利),这很容易出错:

  1. view1读取整个用户实体数据(x =无,y =无)
  2. view2读取整个用户实体数据(x =无,y =无)
  3. view1 user.x = 1(x = 1,y =无)
  4. view2 user.y = 2(x =无,y = 2)
  5. view1 user.put()(x = 1,y =无)
  6. view2 user.put()(x =无,y = 2)
  7. 解决此问题的最佳方法是什么,以及哪种行为被认为最体面?交易(其中一个请求会失败,这可以吗?)

1 个答案:

答案 0 :(得分:2)

包裹您的获取并进入交易。这将确保您无法踩踏不同的更新。

您可以阅读有关transactions with the NDB Client Library文档的更多信息。

在您的代码中,您可以使用NDB事务装饰器:

@ndb.transactional(retries=1)
def view1(request, key):
    user = ndb.Key(urlsafe=key).get()
    user.x = 1
    user.put()
    ...

@ndb.transactional(retries=1)    
def view2(request, key):
    user = ndb.Key(urlsafe=key).get()
    user.y = 2
    user.put()