@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
}
}
注意:交易状态0 =有效。 交易状态1 = markedForRollback
正如我上面的代码所附加的,使用容器管理事务的Ejb singelton bean中存在2种方法。 method_A启动,其transactionAttribute为REQUIRED,因此TransactionSynchronizationRegistry在启动时将事务状态打印为0。引发运行时异常的方法调用后,事务状态自动变为1。但是,当调用具有事务属性REQUIRES_NEW的method_B时,TransactionSynchronizationRegistry仍打印1。据我所知,它应该启动一个新事务,并且在method_B中事务状态应显示为0?
答案 0 :(得分:0)
从同一bean的方法直接调用bean方法不会通过事务拦截器,因此不会进行事务属性检查。
有两种方法可以解决此问题:
@Resource
private ManagedExecutorService mes;
....
mes.execute(()->method_B());
....
这将通过拦截器/代理,并且在另一个线程中将自动启动新事务。这里的缺点是,如果新事务失败,则method_A
中的事务将不会回滚,因为它们位于不同的线程中