次のコードシナリオがあり、A
クラスのメソッドが注釈でa1
マークされておらず@Transactional
、a2
メソッドが@Transactional
注釈でマークされている場合、メソッドでメソッドをa1
呼び出しa2
ます。トランザクションはこの時点で開始されますか?
トランザクションを開始しません。a1
このメソッドはA
、ターゲットクラスのネイティブメソッドです。を呼び出すa1
と、メソッドは直接ターゲットクラスA
に入り、呼び出されます。ターゲットクラス内のA
唯一のa2
ネイティブメソッドには、@Transactional
注釈が付けられa1
ます。ここa2
で呼び出されるのは直接実行されるa2
ネイティブメソッドであり、プロキシオブジェクトを作成することによって呼び出されることはありません。なのでTransactionInterceptor
、に入らないinvoke
メソッドは、トランザクションを開きません。
ことをこの時点で場合a1
、メソッドにマーク@Transactional
注釈、a2
メソッドはマークしません@Transactional
ノートをが、a1
アクセス修飾子のアプローチがそれであるprotected
で、a1
でメソッドを呼び出すa2
方法トランザクションを開始しますか?
トランザクションを開きません。@Transactional
動作メカニズムはAOPに基づいており、AOPは動的プロキシを使用して実装されており、動的プロキシはJDKまたはCglibのいずれかです。上記の分析によると、JDK動的プロキシメソッドの場合、ターゲットクラスのターゲットメソッドがインターフェイスで定義されていること、つまり、public
プロキシされるには変更されたメソッドである必要があることがわかります。Cglibメソッドの場合、プロキシクラスはターゲットクラスのサブクラスであり、理論的にプロキシ化public
およびprotected
メソッドできますが、Springがトランザクション拡張を現在のターゲットクラスに適用できるかどうかを判断できる場合、ターゲットクラスのpublic
メソッドをトラバースするため、Cglibメソッドもpublic
メソッドに対してのみ有効です。
Springフレームワークで宣言的トランザクション処理はどのように実装されていますか?
Springコンテナが各シングルトンBeanを初期化すると、コンテナ内のすべてのBeanPostProcessor
実装クラスをトラバースしてそのpostProcessAfterInitialization
メソッドを実行します。AbstractAutoProxyCreator
クラスのpostProcessAfterInitialization
メソッドを実行すると、コンテナ内のすべてのアスペクトをトラバースして、現在インスタンス化されているBeanに一致するアスペクトを見つけます。ここでは、トランザクション属性アスペクトを取得し、@Transactional
注釈とその属性値を見つけて、取得したアスペクトに基づいてプロキシオブジェクトを作成します。デフォルトでは、JDK動的プロキシを使用してプロキシを作成します。ターゲットクラスがインターフェースの場合はJDK動的プロキシを使用し、それ以外の場合はCglibを使用します。プロキシの作成プロセスでは、現在のターゲットメソッドに対応するインターセプターが取得されます。このとき、TransactionInterceptor
インスタンスが取得されます。そのinvoke
メソッドでは、トランザクションが開始され、ロールバックされます。トランザクション操作が必要な場合、Springはターゲットクラスを呼び出します。ターゲットメソッドがトランザクションを開始する前に、例外を呼び出してトランザクションをロールバックし、呼び出しの完了後にトランザクションを送信します。新しいトランザクションを開始する必要があるかどうかは、@Transactional
アノテーションで構成されたパラメーター値に基づいて決定されます。新しいトランザクションを開始する必要がある場合は、Connection
接続を取得してから、接続の自動コミットトランザクションfalse
を手動送信に変更します。ターゲットクラスのターゲットメソッドが呼び出されると、例外が発生した場合にcompleteTransactionAfterThrowing
メソッドが開始されます。
その実現原理を教えてください。
クラス場合A
に表示されている@Transactional
注釈が、春のコンテナが起動し、クラスがA
プロキシクラスを作成するにはB
、クラスは、A
すべてのpublic
プロキシクラスのメソッドがしますB
クラス、対応するプロキシメソッドを持っている呼び出しA
の1 public
に対応するプロキシ方式を入力するメソッドをでの処理
唯一のクラス場合A
のb
(使用する方法public
に変更が)にマーク@Transactional
注釈、Springコンテナが起動し、クラスがあるA
プロキシクラスを作成することB
が、唯一のクラスA
でb
プロキシメソッドを作成するには、クラスを呼び出すA
のb
方法は、対応するプロキシを入力しますメソッドで処理されるか、クラスのA
他のpublic
メソッドを呼び出すか、クラスのメソッドを入力A
して処理します。プロキシクラスにメソッドを入力する前に、クラスのメソッドTransactionInterceptor
が最初に実行されinvoke
、新しいトランザクションを開くかどうか、トランザクション処理全体のロジックを完了し、ターゲットメソッドの実行中にトランザクションをロールバックする必要があるかどうかを監視し、ターゲットメソッドの完了後にトランザクションを送信します。等
Springフレームワークはトランザクションロールバックを実装していますか?それはすべてのタイプの例外に対してトランザクションロールバック操作を実行しますか?
Springは、すべてのタイプの例外に対してトランザクションのロールバック操作を実行するわけではありません。デフォルトでは、Unchecked Exception
(Error
およびRuntimeException
)に対してのみトランザクションのロールバック操作を実行します。