私の問題を単純化するために、私は持っています
@Transactionnal メソッド createUser() を使用する App1:
- データベースに新しいユーザーを挿入する
- ユーザーが通知メールを受信できるように、RabbitMQ に非同期メッセージを追加します。
- (潜在的にいくつかの追加コードですが、それほど多くはありません)
App2 と RabbitMQ メッセージ コンシューマ
- メーリング キューのメッセージをリアルタイムで消費します
- データベース内のメール データを読み取る
- メールを送る
問題は、App1 でトランザクションがコミットされる前に、App2 が RabbitMQ メッセージを消費しようとする場合があることです。これは、ユーザーがまだ作成されていないため、App2 がデータベース上のメール データを読み取ることができないことを意味します。
いくつかの解決策は次のとおりです。
- App2 で READ_UNCOMMITED 分離レベルを使用する
- RabbitMQ メッセージの配信に遅延を追加します (またはコンシューマーで RetryTemplate を追加します)。
- メールの送り方を変え...
Spring に RabbitTransactionManager があるのを見たことがありますが、それがどのように機能するのか理解できません。トランザクション処理の内部は常に理解しにくいように思われ、ドキュメントもあまり役に立ちません。
このようなことをする方法はありますか?
- @Transactionnal メソッドで RabbitMQ キューにメッセージを追加する
- トランザクションが終了すると、メッセージがキューにコミットされ、変更がデータベースにコミットされます
- DBトランザクションが終了する前にメッセージが消費されないようにする
どのように?たとえば、非同期メッセージの代わりに同期 RabbitMQ メッセージを送信した場合、どうなるでしょうか? 応答または何かを待っているスレッドをブロックしますか? さまざまなユースケースで同期メッセージと非同期メッセージを送信するためです。