如果我们启动一个事务以删除 appengine 上的一个复杂对象,并且该对象附加了一些需要删除的 blob 引用,那么我们就会遇到问题。如果我们只是删除 blob,事务可能会失败,但 blob 已经消失,因为 blobstore 独立工作(这与事务的想法背道而驰)。
现在我们有了这个很酷的新 NDB,它有一个上下文缓存,没有记录的 API(?)可以解决问题。
工具箱:
- ndb.get_context() (未在 ndb 的函数参考中记录)
ndb_context.call_on_commit(delete_blobs_call_on_commit)
def delete_blobs_call_on_commit(): ndb_context = ndb.get_context() blobstore.delete(ndb_context.list_of_blobkeys_to_delete) # OR: taskqueue.add(url+ndb_context.list_of_blobkeys_to_delete)
任务:将事务期间要删除的 blobkey 附加到上下文对象,并在事务后将其删除。
更新: call_on_commit() 不允许数据库操作(可能包括 blobstore.delete,但尚未尝试),并且会抛出 BadRequestError: Cannot start a new operation in a finished transaction,因此唯一的解决方案可能真的是任务队列。
更新:可以从使用 call_on_commit() 注册的函数中调用带有 @ndb.non_transactional 装饰器的函数。因此,可以尝试在提交成功时删除 blob,并希望您没有会导致孤儿的异常。
问题:如何安全地使用上下文缓存?您是如何解决 blob 删除问题的?