と仲良く@ndb.toplevel
遊べる@ndb.transactional
でしょうか?
私が達成したいのは、entity.put_async()
呼び出しを含むトランザクションですが、先物を明示的に待つ必要がないという便利さです。@ndb.toplevel
通常はこれを行いますが、別の SO の質問は、トランザクションと組み合わせることはできないことを示唆しているようです: 「ndb トップレベルはトランザクションを壊しますか?」
これは、App Engine のドキュメントのどこにも明示的に文書化されているのを見つけることができません。put_async()
その質問に示されているアサーション エラーを再現することはできますが、呼び出しが失敗して問題がないかどうかを確認するためにいくつかのテストを作成しました。ただし、データが失われる可能性があるため、ndb をよく知っている人からここでより具体的な回答を得るとよいでしょう。
簡単なテスト コードを以下に示します。ndb.toplevel
とndb.transactional
デコレータの両方を削除すると、予想どおり、テストは失敗します。ただし、デコレータのみを使用してndb.transactional
デコレータを省略したndb.toplevel
場合、テストはパスしますが、これは予期されていません。ndb.transactional
これは、呼び出しが完了するのに十分な時間があるのに十分なオーバーヘッドがあるだけでput_async()
、保証がないので、予期せずに失敗する可能性があるのではないかと心配しています。
class AsyncTestModel(ndb.Model):
data = ndb.StringProperty(indexed=True)
@ndb.toplevel
def start_test():
for _ in range(100):
test()
# Check we wrote all the entities
time.sleep(30)
entities = AsyncTestModel.query().fetch()
assert(len(entities) == 1000)
@ndb.transactional(xg=True)
def test():
for _ in range(10):
x = AsyncTestModel()
x.data = make_random_string(1000)
x.put_async()