@Transactional
public class UserServiceImpl implements UserService {
...................
public void method1(){
try{
method2();
}catch(Exception e){
}
}
public void method2(){
}
}
public class UserServiceImpl implements UserService {
...................
public void method1(){
try{
method2();
}catch(Exception e){
}
}
@Transactional
public void method2(){
}
}
ケース1で例外が発生するとロールバックは機能しますが、ケース2では機能しません。ケース1に従う場合、パフォーマンスの問題はありますか?
ケース1では、@ Transactionalが個々のメソッドすべてに適用されます。ケース2の場合、@ Transactionalはmethod1()ではなくmethod2()にのみ適用されます
ケース1:-method1()の呼び出し->トランザクションが開始されます。 method1()がmethod2()を呼び出すとき、新しいトランザクションは開始されていません。
ケース2:-method1()の呼び出し->トランザクションは開始されません。 method1()がmethod2()を呼び出すとき[〜#〜] no [〜#〜]新しいトランザクションが開始されます。これは、同じクラス内からメソッドを呼び出すときに@Transactionalが機能しないためです。別のクラスからmethod2()を呼び出すと機能します。
スプリングリファレンスマニュアル から:
プロキシモード(デフォルト)では、プロキシを介して着信する外部メソッド呼び出しのみがインターセプトされます。つまり、ターゲットオブジェクトの別のメソッドを呼び出すターゲットオブジェクト内のメソッドは、実際には、呼び出されたメソッドが@Transactionalでマークされていても、実行時に実際のトランザクションにつながりません。また、期待される動作を提供するためにプロキシを完全に初期化する必要があるため、初期化コードでこの機能、つまり@PostConstructに依存しないでください。
クラスの_@Transactional
_は、サービスの各メソッドに適用されます。ショートカットです。通常、すべてのメソッドがリポジトリレイヤーにアクセスすることがわかっている場合は、サービスクラスに@Transactional(readOnly = true)
を設定できます。その後、モデルで変更を実行するメソッドで_@Transactional
_を使用して動作をオーバーライドできます。 1)と2)の間のパフォーマンスの問題は不明です。
次のクラスがあるとします:
_@Transactional(readOnly = true)
public class DefaultFooService implements FooService {
public Foo getFoo(String fooName) {
// do something
}
// these settings have precedence for this method
@Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW)
public void updateFoo(Foo foo) {
// do something
}
}
_
クラスレベルの_@Transactional
_注釈は、クラス内のすべてのメソッドに適用されます。
ただし、、メソッドに_@Transactional
_の注釈が付けられている場合(updateFoo(Foo foo)
など)、これはトランザクション設定よりも優先されますクラスレベルで定義されます。
詳細:
ここ からの引用
Springチームの推奨事項は、インターフェイスに注釈を付けるのではなく、@ Transactional注釈を使用して具体的なクラスにのみ注釈を付けることです。
このメカニズムはプロキシに基づいているため、プロキシを介して着信する「外部」メソッド呼び出しのみがインターセプトされます。つまり、呼び出されたメソッドが@Transactionalでマークされていても、「自己呼び出し」、つまりターゲットオブジェクト内のメソッドがターゲットオブジェクトの他のメソッドを呼び出すと、実行時に実際のトランザクションにつながりません!