I'm working with a DB2 database and tested following code: no matter methodB has Propagation.REQUIRES_NEW or not, if methodB has exception, methodA's result will be committed correctly regardless.
This is against my assumption that Propagation.REQUIRES_NEW must be used to achieve this.
ClassA
@Autowire
private ClassB classB;
@Transactional
methodA(){
...
try{
classB.methodB();
}catch(RuntimeException ex){
handleException(ex);
}
...
}
ClassB
@Transactional(propagation = Propagation.REQUIRES_NEW)
methodB(){...}
Thanks for @Kayaman I think I figured it out now.
The behaviour I saw is because methodB's @Transactional annotation didn't work, so methodB is treated as a normal function without any transaction annotation.
Where it went wrong is that in methodA, I called methodB from a subclasss of ClassB by super.methodB()
and thought that it will give a transactional methodB, which isn't working:
@Service
@Primary
ClassC extends ClassB{
@override
methodB(){
super.methodB();
}
}
I know that transaction annotation will not work if you call a transaction method from another non-transactional method of the same class.
Didn't know that super.methodB()
will also fail for the same reason (anyone can give a bit more explanation pls?)
In conclusion, in the example of the first block of code, when methodB has RuntimeException,
If methodB has NO transaction
annotation: A & B share the same transaction; methodA will NOT rollback
if methodB has REQUIRED
annotation: A & B share the same transaction; methodA will rollback
if methodB has REQUIRES_NEW
annotation: A & B have separate transactions; methodA will NOT rollback