使用JTA时,在另一个EJB中调用函数之前提交事务

时间:2019-04-24 08:33:20

标签: hibernate ejb jta

@Stateless(name =“ A”)     公共类A {

    @PersistenceContext
    private EntityManager entityManager;

    @EJB
    private B serviceB;

    public void doSomeProcessA(List<AnyEntity> entities) {
        for (AnyEntity entity: entities) {
            //do some process.
            entityManager.persist(entity);
            serviceB.b(entity.getPrimaryKey());
        }

    }
}

@Stateless(name = B)
public class B {
    @PersistenceContext
    private EntityManager entityManager;

    @Resource
    private SessionContext sessionContext;

    public void b (String id) {
        AnyEntity entity = entityManager.find(AnyEntity.class, id);

        try {
            //do some process

            entityManager.merge(entity);
        } catch (Exception e) {
            sessionContext.setRollbackOnly();
        }
    }
}

这是我的情况。我想先保留实体。并对b函数中的实体进行其他更改。如果发生任何异常,我想对实体进行事务回滚更新,但我想保留持久实体。

如果我以此代码为例,如果发生任何异常,则不会提交持久实体。如果在函数上使用@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW),服务A上的进程未完成,事务未提交并写入db,则无法访问服务B上的实体。我无法将b更改为b(AnyEntity实体),因为我们使用的业务逻辑。我该怎么办才能解决这个问题。

1 个答案:

答案 0 :(得分:0)

您尝试了吗?

 @Stateless(name = "A") 
 @TransactionManagement(TransactionManagementType.BEAN)
 public class A {

    @PersistenceContext
    private EntityManager entityManager;

    @Resource
    private UserTransaction transaction;

    @EJB
    private B serviceB;

    public void doSomeProcessA(List<AnyEntity> entities) {
        for (AnyEntity entity: entities) {
          try {
            //do some process.
            transaction.begin();

            entityManager.persist(entity);

            transaction.commit();

            serviceB.b(entity.getPrimaryKey());
         } catch (Exception e) {
           try {
             this.transaction.rollback();
               } catch (IllegalStateException | SecurityException
                       | SystemException e1) {
                e1.printStackTrace();
            }
        }

    }
}

@Stateless(name = B)
public class B {
    @PersistenceContext
    private EntityManager entityManager;    

    @Transactional(value = Transactional.TxType.REQUIRES_NEW, rollbackOn = Exception.class)
    public void b (String id) {
        AnyEntity entity = entityManager.find(AnyEntity.class, id);
        //do some process    
        entityManager.merge(entity);
    }
}