需要在其范围结束之前强制持久保存容器管理的事务

时间:2017-06-29 07:40:43

标签: hibernate jpa-2.0 ejb-3.0

我试图在使用entityManager.flush()

的范围结束之前保持容器管理的事务

bean类带注释

@TransactionAttribute(TransactionAttributeType.REQUIRED)

通过这个链接:how we can get JPA EntityManager Flush work,我知道使用entityManager.flush()不会提交事务。 DBMS现在将知道这些数据,但其他数据库会话将无法看到它。

此外,我尝试创建一个带注释的新bean方法

@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)

点击此链接how to commit a transaction in EJB? 在其范围在新bean方法中的其他事务中调用entityManager.flush()。但是这不起作用。

我正在寻找一种强制提交事务的方法,以便在DB中保持其迄今为止的当前状态。

类似的东西:

entityManager.getTransaction().commit();

这可以用于BMT但不能用于CMT。

2 个答案:

答案 0 :(得分:1)

最后,我得到了问题的解决方案。

@Stateless
@TransactionAttribute(TransactionAttributeType.REQUIRED) 
public class OuterBean {

@EJB
PersistingBean bean;
@PersistenceContext
EntityManager em;

public void persistData() {

    em.flush();

    procedureCall();

    Data data = loadExisitingData();
    update(data);
    update(data);

    bean.persistDataInOwnTransaction(data,em);

    em.refresh(getUpdatedEntity())

    externalCall();
}
}

@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)   
 public class PersistingBean {

public void persistDataInOwnTransaction(Data data, EntityManager em) {
em.merge(data);
  }
}

注意:我们很幸运,我们对数据库进行了一次过程调用,因为em.flush()在第一次使用版本1提交了事务,后来在调用em时被覆盖了.merge(data)增加了hibernate版本2.

em.merge(数据) - >在单独的事务中提交数据因此实体将使用在persistDataInOwnTransaction(数据数据,EntityManager em)中作为参数传递的相同enityManager在其自己的事务中在数据库中更新,从而覆盖具有相同em ID的db中的先前实体。 / p>

em.refresh(getUpdatedEntity()) - >从数据库刷新实例的状态,以便对于具有版本3的此实体可以进行任何进一步的提交,就像我们的情况一样,在bean类的范围结束时。

因此最终在DB中不会创建多个记录。每当我们尝试使用递增的休眠版本来保持它时,相同的实体就会被覆盖。

答案 1 :(得分:0)

您可以封装将数据保存到另一个bean中的逻辑,并使用@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)对其进行注释。调用此方法后,持久化数据应该可用。

更新版本
ContainerManagedTranaction(CMT)的示例

@TransactionAttribute(TransactionAttributeType.REQUIRED)    
public class OuterBean {
    @Inject
    PersistingBean bean;

    public void persistData() {
        Data data = loadExisitingData();
        update(data);
        update(data);

        bean.persistDataInOwnTransaction(data);

        externalCall();
    }
}

@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)    
public class PersistingBean {
    @PersistenceContext
    EntityManager em;

    public void persistDataInOwnTransaction(Data data) {
        em.merge(data);
      }
}

BeanManagedTransaction(BMT)的示例
Oracles Java EE Tutorial

@Stateless
@TransactionManagement(TransactionManagementType.BEAN)
public class OuterBean {
    @Resource
    EJBContext context;
    @PersistenceContext
    EntityManager em;

    public void persistData() {
        UserTransaction ut = context.getUserTransaction();

        try {
            ut.begin();
            Data data1 = loadData1();
            update(data1);

            Data data2 = loadData2();
            update(data2);

            ut.commit();
        } catch(Exception ex) {
            ut.rollBack();
        }

        externalCall();
    }
}