在事务中使用 deferred.defer

Using deferred.defer within a transaction

Google 应用引擎 docs 状态:

You can enqueue a task as part of a Google Cloud Datastore transaction, such that the task is only enqueued—and guaranteed to be enqueued—if the transaction is committed successfully.

并给出这个例子:

@ndb.transactional
def do_something_in_transaction():
    taskqueue.add(url='/path/to/my/worker', transactional=True)

但我不清楚使用 deferred 库创建的任务是否也是如此。为此:

@ndb.transactional
def do_something_in_transaction():
    deferred.defer(my_function)

任务是否仅在事务成功提交后才入队?

从根本上说 deferred.defer 只是 taskqueue.add 的包装。从 SDK 的 google/appengine/ext/deferred/deferred.py 文件:

def defer(obj, *args, **kwargs):
  ...
  transactional = kwargs.pop("_transactional", False)
  ...
  try:
    task = taskqueue.Task(payload=pickled, **taskargs)
    return task.add(queue, transactional=transactional)

因此,如果您希望延迟任务以事务方式入队,则只需执行等效操作即可:

@ndb.transactional
def do_something_in_transaction():
    deferred.defer(my_function, _transactional=True)