web-dev-qa-db-ja.com

Spring Transaction ManagementはSpring WebFluxと連携しますか?

SpringによるRDBMSトランザクション管理のサポートは、Spring WebFluxでも機能しますか?

たとえば、適切な構成を前提として、メソッドは@Transactionalアノテーションは、Springトランザクションマネージャを使用して、エラーが発生した場合にトランザクションをロールバックしますか?

トランザクション管理が機能する場合は、@Transactionalメソッドは実際にはthrowと例外、またはMonoまたはFlux戻り値型はエラー信号を出力する必要がありますか?

JDBCは本質的にブロッキングであるため、JDBC操作はブロッキングからリアクティブに、またはその逆にブリッジする必要があります。

SpringトランザクションマネージャーはThreadLocal(正しい?)を使用して機能します。これは、Reactorがスレッドに質素であり、単一のスレッドが1つの作業単位を交換できるため1つ目がI/Oを待機している間にもう1つ。 ReactorにはContextオブジェクトが概念的にはThreadLocalに似ていることを知っています(正しいですか)。さらに、トランザクション内で発生するすべてのJDBC操作は、同じConnectionを使用する必要があります。これは、事後対応コンテキストでは実行が難しい場合があります。

私の組織にはWebFluxとCassandraの経験がありますが、Cassandraにはネイティブのリアクティブドライバーがあります。

ありがとうございました!

11
user3303372

私の知る限り、Springの標準トランザクション管理はWebFluxでは機能しません。

_@Transactional_の使用は機能しません。注釈付きメソッドが呼び出されると、トランザクションメカニズムがトランザクションの状態を呼び出しスレッドのThreadLocal内に保存するためです。自分で言ったように、これは機能しません。ブロックし、状態を共有します。

ただし、ブロッキングコードを別のスレッドに送信するために.runOn(Schedulers.parallel())を使用できます。このようにして、DB接続プールと同じサイズになるように構成できるブロック可能なスレッドを含むスレッドプールを作成できます。

しかし、それでも、トレッドプールがスレッドを再利用する方法が原因で、_@Transactional_に依拠することはできません。標準のサーブレットアーキテクチャでは、HTTPリクエストごとに1つのスレッドがあります。応答が返送されると、スレッドが停止し、トランザクションが閉じます。ただし、この場合、Reactorスケジューラはスレッドを閉じず、他のイベントに再利用します。したがって、ブロックできても、以前と同じ問題が発生します。

あなたはあなたが言及したContextオプションを持っています、そして私はこれがMonoでうまくいくと思います。 Fluxで機能するかどうかはわかりません(Fluxのすべてのイベントが同じコンテキストを共有していると思いますが、これは望ましくありません)。

別のオプションは、ビジネスオブジェクトとして_T1_を含むTouple2を使用し、トランザクションコンテキストとして_T2_を使用することです。ただし、ビジネスロジックと技術的なものを組み合わせて複雑すぎるため、これはお勧めできません。

私の最善の策は、トランザクション/接続管理を自分で行うことです:

  1. DB接続を取得
  2. TXを開く
  3. ブロッキングを行うIOもの
  4. TXを閉じる
  5. DB接続を閉じる/解放する

ブロッキングスレッド上のすべての1つのコードブロック。

これは、より安全で(リークなし)、理解しやすくなります。また、基本的にすべてを自分で行うので、シナリオに最適なエラー処理の種類を選択できます。

2
Liviu Ilea