TransactionAttribute.REQUIRES_NEW不使用容器管理的事务在EJB bean中启动新事务

时间:2018-06-28 20:33:31

标签: transactions ejb-3.0

@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?

1 个答案:

答案 0 :(得分:0)

从同一bean的方法直接调用bean方法不会通过事务拦截器,因此不会进行事务属性检查。

有两种方法可以解决此问题:

@Resource
private ManagedExecutorService mes;


....
mes.execute(()->method_B());
....

这将通过拦截器/代理,并且在另一个线程中将自动启动新事务。这里的缺点是,如果新事务失败,则method_A中的事务将不会回滚,因为它们位于不同的线程中