我试图在使用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。
答案 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();
}
}