This question was asked me in one interview
class A{
@Transactional
public void test1(){
test2();
}
@Transactional(propagation = REQUIRED.NEW)
public void test2(){}
class B extends A{
public void test1(){
super.test1();
}
He asked me how many transaction objects would be created? The answer was 1, not 2. now I am having a hard time struggling with this part. He said this is how CgLib proxy works, can anyone explain this part?
CodePudding user response:
This program can be rewritten like:
class A{
@Transactional
public void test1(){
this.test2(); // this is added
}
@Transactional(propagation = REQUIRED.NEW)
public void test2(){}
class B extends A{
public void test1(){
super.test1();
}
suppose you get A
from application context and call the test1()
method on that:
var a = context.getBean(A.class);
a.test1()
we know that a
is actually the proxy object so a transaction is going to be created. in test1()
method we call this.test2()
method.
From Spring doc:
However, once the call has finally reached the target object any method calls that it may make on itself, such as this.bar() or this.foo(), are going to be invoked against the this reference, and not the proxy
so for test2()
method no transaction is going to be created because this is invoked against the A
class not the proxy class with all transactional stuff support.
Now suppose that you get B
from application context and invoke test1()
method against it.
var b = context.getBean(B.class);
b.test1()
Because B
is the subclass of A
and A
is annotated with Transactional, B
itself is a proxy (@Transactional is automatically inherited even though test1() in B
is not annotated with @Transactional
). so a transaction is going to be created. when we reach the target object all transaction stuff goes away and no more transaction is going to be created like the first case.