sqlalchemyを使用していくつかの関数を書いています。これらの関数は、イベントハンドラを追加する方法は、sqlalchemyでコミットされたトランザクションの後に1回だけ発生します。
def create_order(session, *arg, **kw):
# create order object
order = Order(xxxx=xxx)
session.add(order)
# order extra operations
order_extra_data = OrderExtraData(yyyy=yyyy)
session.add(order_extra_data)
# more operations
....
# email should be sent to the order's owner
のような内部取引と呼ばれ、注文が成功した後、ユーザーに電子メールを送信する必要があります。しかし、create_orderの最後では、トランザクションはまだコミットされておらず、後のコードで中止される可能性があります。したがって、この関数は直接メールを送信すべきではありません。その代わりに、セッションがコミットされた後にのみ起動されるワンタイムイベントハンドラを登録する必要があります(トランザクションがロールバックまたはクローズの場合は起動せずクリアしないでください)。これをどのように実装できますか?
私はイベントに関するドキュメントも読んでいます。 after_commitとafter_soft_rollbackのいずれかが呼び出されることを保証していますか?(session.close()を直接呼び出すとafter_soft_rollbackがトリガーされますか?)なぜafter_rollbackの代わりにafter_soft_rollbackを使用するのですか? – jayven
@jayvenトランザクションがコミット(after_commit')またはロールバック( 'after_soft_rollback')されることが保証されていることはかなり確信しています。私が確信していない唯一のケースは、トランザクションがまだ開始されていない場合ですが、それはほとんど起こりません。 'Session.close'は、セッションが閉じられた後でセッションを再利用することができなくなるので、問題ではありません(作成した新しいセッションには、過去に他のセッションにアタッチしたリスナーはありません)。 'after_soft_rollback'は' session.rollback() 'に対応するイベントですので、これを使用してください。 'after_rollback'はSQLの' ROLLBACK'に対応します。 – univerio
Thxあなたの説明のために、これは私をたくさん助けます。 – jayven