https://github.com/spring-projects/spring-framework/blob/5b2ace57423148bc9fd6af864e4c7c1eb04d515b/spring-tx/src/main/java/org/springframework/transaction/interceptor/TransactionAspectSupport.java#L341
Hi, I have two services:
class ServiceA {
@Autowired
public serviceB serviceB;
@Transactional(propagation = Propagation.REQUIRES_NEW, noRollbackFor = {IllegalArgumentException.class})
public void methodA(){
....
serviceB.methodB()
}
}
class ServiceB {
@Transactional(propagation = Propagation.REQUIRED)
public void methodB(){
....
throw new IllegalArgumentException();
}
}
Unfortunately, my transaction is rolled back.
Can I change something in this behavior? Can we check to exist transaction info before checking this info by class and method?
Or is it correct at all?
Comment From: kongwu-
You should write noRollbackFor
on ServiceB
Comment From: sbrannen
@kongwu-'s answer is correct.
You need to either redeclare noRollbackFor = IllegalArgumentException.class
in service B or move the declaration completely to service B.
This is by design: @Transactional
defines the transaction attributes for the given transactional scope, and transaction attributes are not inherited by enclosed scopes. In your example, service A is the surrounding transactional scope, and service B is the enclosed transactional scope. So, although service B participates in the transaction started for service A, service A's noRollbackFor
rollback rule does not apply to exceptions thrown within service B's scope. When an IllegalArgumentException
is thrown within service B's transactional scope, TransactionAspectSupport#completeTransactionAfterThrowing(TransactionInfo, Throwable)
will indirectly set the "rollback only" flag to true
for the surrounding transaction (i.e., the transaction started for service A).
In light of that, I am closing this issue.
Comment From: denis111
I had the same problem but the solution was inverse!. It had noRollbackFor on serviceB and it didn't work, I put the same noRollbackFor on serviceA and it worked! Did this behavior change then?