【问题标题】:TransactionAttribute.REQUIRES_NEW not starting new transaction in EJB bean using container managed transactionTransactionAttribute.REQUIRES_NEW 未使用容器管理事务在 EJB bean 中启动新事务
【发布时间】:2018-06-28 20:33:30
【问题描述】:
@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 = active
  • 交易状态1 = markedForRollback

正如我附上了上面的代码,在使用容器管理事务的 Ejb 单点 bean 中存在 2 个方法。 method_ATransactionAttributeREQUIRED 开始,因此 TransactionSynchronizationRegistry 在开始时将事务状态打印为 0

在抛出运行时异常的方法调用后,事务状态自动变为1。但是当一个method_B 的事务属性为REQUIRES_NEW 被调用时,TransactionSynchronizationRegistry 仍然打印1

据我了解,它应该开始一个新事务,并且事务状态应该在method_B 中显示为0

【问题讨论】:

    标签: java transactions ejb-3.0


    【解决方案1】:

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

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

    @Resource
    private ManagedExecutorService mes;
    
    
    ....
    mes.execute(()->method_B());
    ....
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-25
      • 2015-11-26
      • 2017-03-29
      • 2013-07-24
      相关资源
      最近更新 更多