1. ホーム

[解決済み】Spring - @Transactional - バックグラウンドで何が起こっているのか?

2022-03-25 05:25:31

質問

でアノテートした場合、実際に何が起こるのか知りたい。 @Transactional ? もちろん、SpringがそのメソッドをTransactionでラップすることは知っている。

しかし、次のような疑問があります。

  1. Springでは プロキシクラス ? 誰かもっと詳しく説明してください 深さ . そのプロキシクラスに実際に存在するのは何でしょうか?実際のクラスはどうなるのでしょうか?また、Springが作成したプロキシクラスを見るにはどうすればいいのでしょうか?
  2. また、Springのドキュメントにはこう書かれています。

注)この仕組みはプロキシを利用しているため。 プロキシを経由して入ってくる「外部」メソッドコールのみがインターセプトされます。 . つまり、「自己呼び出し」、つまりターゲットオブジェクト内のメソッドがターゲットオブジェクトの他のメソッドを呼び出す場合、呼び出されたメソッドに @Transactional !

出典 http://static.springsource.org/spring/docs/2.0.x/reference/transaction.html

なぜ、外部メソッド呼び出しだけがトランザクションの対象となり、自己呼び出しメソッドは対象とならないのですか?

解決方法は?

これは大きなトピックです。Springのリファレンスドキュメントでは、複数の章を割いて説明しています。に関するものを読むことをお勧めします。 アスペクト指向プログラミング トランザクション Springの宣言的なトランザクションのサポートは、その基盤でAOPを使用しているためです。

しかし、非常に高いレベルでは、Spring は @Transactional をクラス自身またはメンバに追加します。プロキシは実行時にはほとんど見えません。これは、Springがプロキシされるオブジェクトにメソッド呼び出しの前、後、またはその周辺の動作を注入する方法を提供します。トランザクション管理は、フックできる動作の一例です。セキュリティチェックもそのひとつです。また、ロギングのように独自のものを提供することもできます。ですから、あるメソッドに @Transactional Springはアノテーションしたクラスと同じインターフェイスを実装したプロキシを動的に作成します。そしてクライアントがあなたのオブジェクトを呼び出すと、その呼び出しはインターセプトされ、プロキシ機構を介して振る舞いが注入されます。

ちなみに、EJBのトランザクションも同じような仕組みになっています。

お気づきのように、プロキシの仕組みは、外部のオブジェクトから呼び出されたときだけ機能します。オブジェクトの内部で呼び出しを行う場合、実際には this 参照で、プロキシをバイパスします。しかし、この問題を回避する方法はあります。私はその方法の一つを このフォーラムの投稿 を使用しています。 BeanFactoryPostProcessor を使用して、プロキシのインスタンスを実行時に "自己参照" クラスに注入します。この参照を me . それから、スレッドのトランザクションの状態を変更する必要がある内部呼び出しを行う必要がある場合、私はプロキシを通して呼び出しを指示します(例. me.someMethod() .) フォーラムの投稿で詳しく説明されています。

ただし BeanFactoryPostProcessor のコードは、Spring 1.xの時代に書かれたものなので、今は少し違っているでしょう。でも、これがヒントになれば幸いです。私は更新されたバージョンを持っているので、おそらく利用可能にすることができるでしょう。