【发布时间】:2020-01-06 22:09:08
【问题描述】:
我有一些代码可以在_post_put_hook 中排队一个任务。
该任务检索密钥并获取实体。但是,有时工作程序会失败,因为该键的对象尚未创建,但下次运行时会成功。请注意,我们是通过键检索对象,所以我希望数据是一致的。
我只是在提交时调用入队,所以我希望在任务运行时创建对象。在下面的示例中,我发现_post_put_hook 不在事务中,这似乎是导致问题的原因,但为什么不在事务中?
这是一个示例:
@ndb.synctasklet
def log_usage(self):
@ndb.transactional_tasklet(xg=True)
def _txn():
yield Log.insert_document_log_async()
yield _txn()
class Log(ndb.Expando):
@classmethod
@ndb.tasklet
def insert_document_log_async(cls):
log = cls()
logging.debug("insert document log in transaction: {}".format(ndb.in_transaction()))
yield log.put_async()
@ndb.synctasklet
def _post_put_hook(self, future):
@ndb.synctasklet
def _callback_on_commit():
key = future.get_result()
yield SqlTaskHelper.enqueue_syncronise_sql_model_async(key)
logging.debug("_post_put_hook In transaction: {}".format(ndb.in_transaction()))
ndb.get_context().call_on_commit(lambda: _callback_on_commit())
代码执行如下:
-
调用
log_usage调用insert_document_log_async - 调用
insert_document_log_async时,日志记录表明我们处于事务中(在事务中插入文档日志:True)。 - 但
_post_put_hook日志记录表明我们不在事务中(因此 call_on_commit 会立即执行,我怀疑这是问题所在)。该任务不久后运行,实体并不总是可用。
我想知道为什么_post_put_hook 在事务之外执行。
谢谢
【问题讨论】:
标签: python google-app-engine app-engine-ndb