トランザクション障害のシナリオを説明する前に、まず AOP を導入する必要があります。AOP@Transaction
は AOP を通じて実装されるためです。
AOP は実際には Bean オブジェクトを生成するプロキシ オブジェクトです。Bean が作成および初期化されるときに、それがトランザクション アノテーションを持つメソッドである場合、プロキシ クラスを形成するように拡張されます。春には、動的プロキシには 2 つの方法があります。
- JDKダイナミックプロキシ:オリジナルオブジェクトをプロキシオブジェクト内に配置し、含まれるオリジナルオブジェクトを呼び出すことでオリジナルのビジネスロジックを実現します。これがデコレータモードです。プライベート、プロテクト、およびファイナル メソッドは、インターフェイスでサポートされていないため、プロキシ化しないでください。また、静的メソッドはサポートされていません。
- CGLIB 動的プロキシ: 元のオブジェクトのサブクラスを生成し、そのサブクラスは親クラスのメソッドをオーバーライドして親クラスを拡張します。
- サブクラスも他のクラスもクラスのプライベート メソッドにアクセスできないため、プライベート メソッドをプロキシしてはなりません。
- 保護されたメソッドはプロキシ可能ですが、CGLIB は継承関係に基づいて実装されており、生成されたプロキシ クラス内の保護されたプロキシ メソッドも保護され、アクセス範囲が制限されます。
- 最終的に変更されたメソッドはサブクラスによってオーバーライドできないため、最終的に変更されたメソッドをプロキシすることはできません。最終的に変更されたクラスは継承できないため、最終的に変更されたクラスをプロキシすることはできません。
- 静的メソッドはプロキシ化できません。
春のトランザクション失敗シナリオは次のとおりです。
- メソッドは、final メソッドまたは非パブリック メソッドです。Spring では、AOP がサポートしていないため、プロキシされたメソッドが public であり、最終的に変更されていない必要があります。
- メソッドの内部呼び出し: AOP はプロキシ オブジェクトを生成するため、メソッドにはトランザクションの機能がありますが、メソッドが内部で呼び出される場合、プロキシ オブジェクトは使用されないため、トランザクションは存在しません。
- Spring によって管理されない: Spring によって管理されず、AOP によって拡張されません。
@EnableTransactionManagement
開かれていないトランザクション:トランザクションを開くには、エントリ クラスでアノテーションを使用する必要があります。- テーブルはトランザクションをサポートしていません: MySQL5.5 より前のデフォルトのストレージ エンジンは Myisam であり、Myisam はトランザクションをサポートしていません。使用するデータベースがトランザクションをサポートしていない場合、当然トランザクション機能は使用できません。
- メソッドのトランザクション伝播タイプはトランザクションをサポートしていません: 内部メソッドのトランザクション伝播タイプがトランザクションをサポートしていない伝播タイプである場合、内部メソッドのトランザクションも Spring で失敗します。
@Transactional(propagation = Propagation.NOT_SUPPORTED)
- 間違ったアノテーション例外タイプ:
@Transactional
アノテーションに間違った例外タイプがアノテーションされている場合、Spring トランザクションのロールバックは無効になります。Spring のデフォルトのロールバックのトランザクション例外タイプは RuntimeException です。コードが Exception 例外をスローした場合、トランザクションはキャッチできません。もちろん、rollbackFor
プロパティを手動で設定して、指定された例外をキャッチすることもできます。 - 間違ってキャッチされた例外: メソッド内の例外がキャッチされ、メソッド内の try-catch によって処理された場合、例外は渡されず、トランザクションはトリガーされません。
- マルチスレッド呼び出しの問題: 新しいスレッドがメソッド内で SQL 操作を実行できるようになっている場合、そのスレッドはロールバックされません。Spring のトランザクションは ThreadLocal を通じてスレッドセーフです。トランザクションは現在のスレッドにバインドされており、複数のスレッドがあると当然トランザクションは無効になります。
さらに詳しく知りたい場合は、私の個人ウェブサイト「Yetong Space」をご覧ください。