Spring では、@Transaction のようなアノテーションにより、開発者はトランザクションを簡単に管理できます。ただし、トランザクション メソッド (@Transactional) を定義されているのと同じクラス内から呼び出そうとすると、特有の問題が発生します。
具体的には、開発者は、同じクラス内の呼び出し元メソッドが次のような状況に遭遇する可能性があります。 @Transactional メソッドは、期待されるトランザクション動作をトリガーできません。この問題に対処するために、根本的な理由を詳しく調べてみましょう。
Spring のデフォルトのトランザクション処理メカニズムは、CGLIB を使用して Java クラスを動的に生成および拡張し、Spring Bean のプロキシを作成します。ただし、CGLIB は、同じクラス内でメソッド呼び出しを処理するときに制限に直面します。その結果、同じクラス内から @Transactional メソッドを呼び出すと、CGLIB はトランザクションのインターセプトに失敗し、トランザクション動作がなくなります。
この問題の解決策は、アスペクト指向プログラミング (AOP) を利用してトランザクションを処理することにあります。 AOP を使用すると、ソース コード自体を変更せずにプログラムの動作をインターセプトして変更できます。
トランザクション管理に AspectJ を使用するように Spring を設定するには、次の設定を追加する必要があります:
<tx:annotation-driven mode="aspectj"/>
3.0 より前の Spring バージョンを使用している場合は、以下も行う必要がありますadd:
<bean class="org.springframework.transaction.aspectj.AnnotationTransactionAspect" factory-method="aspectOf"> <property name="transactionManager" ref="transactionManager"/> </bean>
もう 1 つの実行可能な解決策 (特に AOP が実現できない場合) は、コードをリファクタリングすることです。同じクラス内からトランザクション メソッドを呼び出す代わりに、トランザクション処理をトランザクション メソッドに委任する別のクラスを作成します。このアプローチにより、Spring のデフォルトのトランザクション処理メカニズムが正しく機能することが保証されます。
以上がSpring で同じクラス内のメソッドを呼び出すときに @Transactional が機能しないのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。