应用引擎链接延迟交易任务

时间:2017-03-03 02:09:06

标签: google-app-engine app-engine-ndb deferred transactional

当我从事务函数调用延迟事务任务时,ff可以在延迟任务失败时提交。

然而,如果我通过延期通话呼叫f,则呼叫功能会失败。

重申,我做了以下事情:

@ndb.transactional()
def f():
  # modify datastore entity X
  ... 
  x.put()

class X(ndb.Model):
  ...
  def _post_put_hook(self, future)
    deferred.defer(y,
                   _transactional=ndb.in_transaction())
def y():
  raise Exception()

当我致电f时,延期任务失败,但x.put()提交。

但是,如果我调用deferred.f,x.put()会失败。

1 个答案:

答案 0 :(得分:0)

我认为你误解了1 * 1 = 1. Future<Integer> = 1 - match 2 * 2 = 4. Future<Integer> = 4 - match 3 * 3 = 9. Future<Integer> = 9 - match 4 * 4 = 16. Future<Integer> = 16 - match 5 * 5 = 25. Future<Integer> = 25 - match 6 * 6 = 36. Future<Integer> = 36 - match 7 * 7 = 49. Future<Integer> = 49 - match 8 * 8 = 64. Future<Integer> = 64 - match 9 * 9 = 81. Future<Integer> = 81 - match 10 * 10 = 100. Future<Integer> = 100 - match _transactional可选参数的作用。它并不意味着延迟的deferred.defer(y, _transactional=ndb.in_transaction())执行将发生在调用y的同一事务中,它只意味着将延迟任务排入队列如果交易成功,将发生

来自google.appengine.ext.deferred.deferred module

  

google.appengine.ext.deferred.deferred.defer(obj,* args,** kwargs)

     

[...]

     
      
  • obj - 要执行的可调用对象。有关限制,请参阅模块docstring。 _countdown,_eta,_headers,_name,_target,    _transactional ,_ url,_ retry_options,_queue:传递到任务队列 - 有关详细信息,请参阅任务队列文档。
  •   

来自google.appengine.api.taskqueue.taskqueue module

  

add(task,transactional = False)

     

[...]

     
      
  • transactional - 如果deferred.defer(),事务任务将被添加到队列中,但在事务发生之前无法运行或租用   成功。如果事务失败,则将从中删除任务   队列(因此​​永远不会运行)。如果True,则添加任务   可立即运行;任何封闭交易的成功   或失败被忽略。
  •   

延迟任务的实际执行是在另一个请求上完成的,总是在与调用False的事务上下文不同的事务上下文中。这就是为什么即使您的原始交易成功,您的延期任务也可能失败。