Reputation: 699
@Singelton
public Class className {
@Resource
private TransactionSynchronizationRegistry tsr;
@Resource
private Transaction
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public method_A () {
System.out.println(tsr.getTransactionStatus()); // prints 0
method_call_which_throw_persistence_exception();
System.out.println(tsr.getTransactionStatus()); // prints 1
method_B();
}
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public method_B () {
System.out.println(tsr.getTransactionStatus()); // prints 1
}
}
Note:
0 = active
.1 = markedForRollback
As i have attached the code above, 2 methods are present in a Ejb singelton bean which is using container managed transaction. method_A
starts which have TransactionAttribute
as REQUIRED
thus TransactionSynchronizationRegistry
prints transaction status as 0
in starting.
After a method call which throw runtime exception transaction status becomes 1
automatically. But when a method_B
which have transaction attribute as REQUIRES_NEW
is called still TransactionSynchronizationRegistry
prints 1
.
As per my understanding it should start a new transaction and the trasaction status should show as 0
in method_B
?
Upvotes: 2
Views: 2275
Reputation: 3533
A direct call on the bean method from a method of the same bean does not go through the transaction interceptor and hence no transaction attribute check is done.
There are 2 ways to solve this:
@Resource
private ManagedExecutorService mes;
....
mes.execute(()->method_B());
....
This will go through the interceptor/proxy and also being in a different thread will automatically start a new transaction. the drawback here is that if the new transaction fails the one in method_A
will not be rolled back as they are in different threads
Upvotes: 3