ホームページ >Java >&#&チュートリアル >同じクラス内で呼び出すと Spring トランザクションが失敗するのはなぜですか?

同じクラス内で呼び出すと Spring トランザクションが失敗するのはなぜですか?

Barbara Streisand
Barbara Streisandオリジナル
2024-12-20 06:09:10458ブラウズ

Why Do Spring Transactions Fail When Called Within the Same Class?

同じクラス内のトランザクション呼び出し: Spring のジレンマ

問題

Spring では、通常、トランザクション メソッドには @Transaction アノテーションが付けられます。トランザクションメソッドが呼び出されると、Spring はトランザクションのライフサイクルを自動的に管理し、例外が発生した場合でもデータの整合性を確保します。ただし、トランザクション メソッドが同じクラス内から呼び出される場合、予期しない動作が発生します。トランザクションはバイパスされているようで、開発者は頭を悩ませています。

原因: 動的プロキシの制限

Spring は動的プロキシ (CGLIB など) を使用してメソッド呼び出しをインターセプトし、トランザクション動作を適用します。ただし、トランザクション メソッドが同じクラス内の別のトランザクション メソッドを呼び出す場合、動的プロキシはバイパスされます。これは、ターゲット オブジェクトがどちらの場合も同じであり、プロキシが外部メソッド呼び出し用にのみ作成されるためです。

解決策: AspectJ またはリファクタリングの採用

この問題を解決するには、次の手順を実行します。 2 つのオプション:

  1. Configuration AspectJ: Spring が提供するAspectJ を使用する代替トランザクション処理モード。 @TransactionManagement アノテーションでmode属性をaspectjに設定すると、SpringはAspectJを使用してトランザクションを管理します。これにより、同じクラス内のトランザクション呼び出しが期待どおりに機能するようになります。
  2. リファクタリング コード: AspectJ はソリューションを提供しますが、最も洗練されたアプローチではない可能性があります。よりクリーンな代替方法は、コードをリファクタリングしてトランザクション操作を異なるクラスに分離することです。各トランザクション操作を専用のクラスで処理させることで、同じクラス内でトランザクション呼び出しがネストされる問題を回避できます。

AspectJ の設定ヒント

トランザクション処理用に AspectJ を設定するには、次のようにします。次の手順に従います:

  • 3.0 より前の Spring バージョンの場合は、次の Bean 定義も設定に追加します。

    <bean class="org.springframework.transaction.aspectj.AnnotationTransactionAspect" factory-method="aspectOf">
      <property name="transactionManager" ref="transactionManager" />
    </bean>

AspectJ を採用するか、コードをリファクタリングすると、Spring のデフォルトのトランザクション処理の制限を克服し、内部でネストされた呼び出しであっても、一貫したトランザクション動作を保証できます。同じクラスです

以上が同じクラス内で呼び出すと Spring トランザクションが失敗するのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。