在另一个事务处于活动状态时手动启动新事务

时间:2015-09-23 08:46:42

标签: jpa transactions ejb

我想在已经处于活动交易中的以下步骤

  1. 插入/更新一些记录
  2. 选择所有那些记录在非实体副本的内存中保存
  3. 回滚第一步而不回滚父事务
  4. 返回第2步的结果。
  5. 我有这个

    @Stateless
    public class DBWorker {
    
        public Result doWork(boolean isPreview) {
            Result result;
    
            if(isPreview) {
                em.getTransaction().begin();
            }
            doSomeWork();
            List<SomeEntity> resultOfDoSomeWork = em.createQuery(..).getResultList();
            result = copyToNonEntity(resultOfDoSomeWork);
    
            if(isPreview)
                em.getTransaction().rollback();
    
            return result;
        }
    }
    

    但是提供例外A JTA EntityManager cannot use getTransaction() IllegalStateException:A JTA EntityManager cannot use getTransaction()

1 个答案:

答案 0 :(得分:1)

您必须使用@TransactionAttribute注释来注释EJB方法。

特别是,你必须做这样的事情:

@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public void myMethod() {
   // do something
}

REQUIRES_NEW表示必须为业务方法启动新事务。

注意将方法调用到另一个EJB,因为如果从同一个EJB调用它,则不会创建新事务。

ROLLBACK

您可以回滚容器管理的事务:

  1. 抛出RuntimeException:容器将自动回滚事务。
  2. 抛出由@ApplicationException(rollback=true)注释的自定义异常:
  3. 通过调用setRollbackOnly接口的EJBContext方法:强制容器回滚事务,如果没有异常也是如此。
  4. 例如:

    抛出RuntimeException:

    try {    
       // do something
    } catch(SQLException e) {
       throw new EJBException();    
    }
    

    抛出自定义异常:

    try {
       // do something
    } catch(SQLException e) {
       throw new MyCustomException();
    }
    

    其中MyCustomException类类似于:

    @ApplicationException(rollback=true)
    public class MyCustomException extends Exception {
       // your custom methods
    }
    

    通过调用setRollbackOnly方法:

    Context.setRollbackOnly();