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にはネイティブのリアクティブドライバーがあります。
ありがとうございました!
私の知る限り、Springの標準トランザクション管理はWebFluxでは機能しません。
_@Transactional
_の使用は機能しません。注釈付きメソッドが呼び出されると、トランザクションメカニズムがトランザクションの状態を呼び出しスレッドのThreadLocal
内に保存するためです。自分で言ったように、これは機能しません。ブロックし、状態を共有します。
ただし、ブロッキングコードを別のスレッドに送信するために.runOn(Schedulers.parallel())
を使用できます。このようにして、DB接続プールと同じサイズになるように構成できるブロック可能なスレッドを含むスレッドプールを作成できます。
しかし、それでも、トレッドプールがスレッドを再利用する方法が原因で、_@Transactional
_に依拠することはできません。標準のサーブレットアーキテクチャでは、HTTPリクエストごとに1つのスレッドがあります。応答が返送されると、スレッドが停止し、トランザクションが閉じます。ただし、この場合、Reactorスケジューラはスレッドを閉じず、他のイベントに再利用します。したがって、ブロックできても、以前と同じ問題が発生します。
あなたはあなたが言及したContext
オプションを持っています、そして私はこれがMono
でうまくいくと思います。 Flux
で機能するかどうかはわかりません(Fluxのすべてのイベントが同じコンテキストを共有していると思いますが、これは望ましくありません)。
別のオプションは、ビジネスオブジェクトとして_T1
_を含むTouple2を使用し、トランザクションコンテキストとして_T2
_を使用することです。ただし、ビジネスロジックと技術的なものを組み合わせて複雑すぎるため、これはお勧めできません。
私の最善の策は、トランザクション/接続管理を自分で行うことです:
ブロッキングスレッド上のすべての1つのコードブロック。
これは、より安全で(リークなし)、理解しやすくなります。また、基本的にすべてを自分で行うので、シナリオに最適なエラー処理の種類を選択できます。