私はレガシーアプリケーションに取り組んでいます。JDBC から Spring 3.2 + Hibernate 4.1.12 + 宣言型トランザクションを持つ JTA 2 に移行しています。Container-Managed Transactions (CMT) が期待どおりにトランザクションとロールバックを行っていることがわかります。2 次キャッシュ (2LC) として Infinispan を使用しています。しわが一つ…
別のスレッドで実行され、プログラムによるトランザクションまたは Bean 管理トランザクション (BMT) を使用する別のエントリ ポイントを持つコードの一部があります。BMT パスでは、CMT を使用している下層のサービス レイヤーで、期待どおりにトランザクションが BMT と結合していることがわかります。
永続化ユニット、データ ソースなどは、両方のエントリ ポイントで同じです。どちらの場合も、Hibernate autoflush コードはトランザクションがあることを認識し、データベース ドライバーにフラッシュします。CMT エントリ ポイントでは、データベース ドライバは、コミットまたはロールバックが指示されるまでデータを保持します。BMT パスでは、データはフラッシュ時にデータベースにプッシュされます。後でコミットまたはロールバックしても、何の効果も明白な意味もありません。トランザクション マネージャは JtaTransactionManager です。JtaTransactionManager は、要素ではなく CMT を有効にする @EnableTransactionManagement を使用して @Configuration クラスで定義され<tx:annotation-driven/>
ます。
シングルトン JtaTransactionManager Bean は、 および を介して ajuna UserTransaction および TransactionManager と接続されていjtaPropertyManager.getJTAEnvironmentBean().getTransactionManager()
ますjtaPropertyManager.getJTAEnvironmentBean().getUserTransaction()
。UserTransaction と TransactionManager はどちらもプロトタイプの @Bean 定義です。
デバッグ中に動作を確認するために、別のクエリ ツールからのクエリによって、データがデータベースにあるかどうかを確認できます。
単体テストを行っているとき、BMT と CMT の両方のエントリ ポイントで期待どおりにデータがコミットされ、ロールバックされます。
BMT は、異なるメソッドでトランザクションの開始と終了を行うクラスによって管理されます。また、実際の作業単位を実行するメソッドもあります。BMT のトランザクションは、TransactionTemplate ではなく、PlatformTransactionManager で開始されます。クラスは、ロジック フローを管理するロジックを持つ別のクラスによって駆動されます。トランザクションが期待どおりに開始および終了していることはわかっています。他のさまざまな議論を読むと、トランザクション制御は単一のメソッド内にある必要があることが暗示されているようです。これが好ましいことに同意しますが、それは不可欠ですか?
Spring の CMT 管理サーブレットが新しい Thread を生成し、計画 thread.start() でスレッドを開始する場合、その新しい Thread 内の BMT が上記のようにそのトランザクションを管理できると期待するのは合理的ですか?
データソースは JNDI によって取得されます。XA を使用しても非 XA を使用しても、結果には影響しません。
コードを投稿できません。
参考までに、第 11 章のトランザクションに関する Spring 3.1 ドキュメントへのリンクを次に示します。
2013/10/04 追加- Spring は を使用して、認識されたコンテナーに基づいてJtaTransactionManagerBeanDefinitionParser
必要なものを構築するようです。JtaTransactionManager
これを使用すると、JTA トランザクション マネージャーはafterPropertiesSet
、UserTransaction、TransactionManager、および TransactionSynchronizationRegistry でそれ自体に設定されます。
私は実際にCMTでデータをリークしているようですが、トランザクションは通常コミットされるため、デバッガーや不自然にエラーを強制しないと、これを認識/観察するのは困難です。
私の問題は、JCA が別の TransactionManager を使用するように、JCA を部分的にバイパスしたことのようです。
部分的な回答- CMT と BMT の混合でこのトランザクションが適切に行われるのを見たので、BMT トランザクションを 1 つのメソッドで開始し、別のメソッドでコミットすることが可能であることを知っています。
疑問が残ります。Spring の CMT 管理のサーブレットが新しいスレッドを生成し、スレッドを計画 thread.start() で開始する場合、その新しいスレッド内の BMT が記述されているようにそのトランザクションを管理できると期待するのは合理的ですか?その上?