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



>@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 上完成,事务未提交并写入数据库,我无法访问服务 B 上的实体。由于我们使用的业务逻辑,我无法将b更改为b(AnyEntity实体(。我能做些什么来解决这个问题。

你试过吗?

 @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);
    }
}

最新更新