appengine で複雑なオブジェクトを削除するトランザクションを開始し、そのオブジェクトに削除する必要のある BLOB 参照がアタッチされている場合、問題が発生します。ブロブを削除するだけでは、トランザクションは失敗する可能性がありますが、ブロブストアは独立して動作するため、ブロブはなくなります (これはトランザクションの考え方に反します)。
今、私たちは問題を解決できる文書化された API(?) のないインコンテキスト キャッシュを持つ、このクールな新しい NDB を手に入れました。
ツールチェスト:
- 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)
タスク: トランザクション中に削除するブロブキーをコンテキスト オブジェクトにアタッチし、トランザクション後に削除します。
更新: call_on_commit() はデータベース操作 (blobstore.delete を含む可能性がありますが、試したことはありません) を許可せず、BadRequestError: Cannot start a new operation in a finished transaction をスローします。そのため、唯一の解決策は本当にタスクキューである可能性があります。
更新: call_on_commit() で登録された関数から @ndb.non_transactional デコレータを使用して関数を呼び出すことができます。そのため、コミットが成功したときに BLOB を削除しようとする可能性があり、孤立につながる例外がないことを願っています。
質問: インコンテキスト キャッシュを安全に使用するにはどうすればよいですか? ブロブ削除の問題をどのように解決しましたか?