【问题标题】:app engine chaining deferred transactional tasks应用引擎链接延迟的事务性任务
【发布时间】:2017-03-03 02:09:06
【问题描述】:

当我从事务函数调用延迟事务任务时,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() 会失败。

【问题讨论】:

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


    【解决方案1】:

    我认为您误解了 _transactional 中的 deferred.defer(y, _transactional=ndb.in_transaction()) 可选参数的作用。这并不意味着延迟的y 执行将发生在调用deferred.defer()同一个事务中,这仅意味着将延迟的任务入队会发生如果交易成功。

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

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

    [...]

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

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

    add(task, transactional=False)

    [...]

    • 事务性 - 如果True,事务性任务将被添加到队列中,但在事务完成之前不能运行或租用 成功。如果事务失败,则任务将从 队列(因此​​永远不会运行)。如果False,添加的任务 可以立即运行;任何封闭交易的成功 或失败被忽略。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-27
      • 1970-01-01
      • 2018-10-21
      • 1970-01-01
      • 1970-01-01
      • 2015-09-14
      相关资源
      最近更新 更多