Transactions CDI事务管理
我正在做一个从JBossSeam到CDI的迁移项目。 以下是技术堆栈: 1) WildFly 8.2.0(CDI 1.2,以Weld作为CDI供应商) 2) JSF2.2 3) JPA 2 我们正在使用容器管理的JTA事务:Transactions CDI事务管理,transactions,cdi,wildfly-8,jpa-2.1,Transactions,Cdi,Wildfly 8,Jpa 2.1,我正在做一个从JBossSeam到CDI的迁移项目。 以下是技术堆栈: 1) WildFly 8.2.0(CDI 1.2,以Weld作为CDI供应商) 2) JSF2.2 3) JPA 2 我们正在使用容器管理的JTA事务: <?xml version="1.0" encoding="UTF-8"?> <persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1"
xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://xmlns.jcp.org/xml/ns/persistence
http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
<persistence-unit name="surveillenace" transaction-type="JTA">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<jta-data-source>java:/surveillenaceDS</jta-data-source>
<!-- other configurations not shown here -->
</persistence>
3) 考虑以下使用上述配置执行的简单场景:
Component1.somemethod()
-在事务内部运行,持久化实体(例如:用户)并提交事务。
在此之后,将按如下方式调用Component2:Component2.somemethod()
-在事务内部运行,但实体用户似乎没有处于管理状态,即em.contains(User)
返回false。
我必须再次合并此实体,以使其能够被管理或再次从持久性存储重新加载
由于Seam使用会话范围的实体管理器
,因此即使任何组件提交事务并在其后调用另一个组件,所有实体实例仍保持在托管状态(在持久上下文中)。
但在CDI案例中,据我所知,这是由于“事务范围的实体管理器”
造成的。一旦事务提交,所有实体实例都将分离。
如何使用CDI实现与Seam相同的效果 CDI不提供事务管理实现作为其规范的一部分。事务管理由程序员通过拦截器来实现,拦截器将负责所有的基础工作,如开始提交等 通常,EntityManager在事务的时间跨度内存在。在seam 2中,您已经扩展了持久性上下文,因此它在多个请求之间保持状态和bean的连接。CDI没有提供,而且由于可伸缩性的原因,它不建议这样做。如果你看一下DeltaSpike,我强烈建议在从Seam2迁移到CDI的情况下,他们提供了一个延长EntityManager寿命的选项,将其推广到对话范围,但他们也不推荐这种方法
这里有DeltaSpike治疗您的问题的文档:
Deltaspike是一个很好的绑定解决方案,文档非常短,所以我建议您使用它,此外,它是由具有seam背景的人员创建的,并提供开箱即用的事务管理。回答您的问题并澄清之前的答案,该答案在您使用Java EE 7/CDI 1.2时仅针对Java EE 6/CDI 1.0
@Transactional
,实现必须提供匹配的拦截器。在WildFly下,您的问题的答案在JBoss JTA实现中:Narayana。您将找到@事务(必需)
拦截器。其他的都在同一个包裹里关于JavaEE6,您的答案是正确的,但在JavaEE7中,您的答案是错误的。JTA1.2提供了
@Transactional
拦截器绑定和拦截器实现。当然,你是对的,我的观点是正确的,我意识到J EE 7提供了@Transactional拦截器我出于某种原因考虑了CDI 1.0,我想,很抱歉,不知何故错误地给出了答案
@Transactional
public String finishOperation() {
log.debug("in finishOperation() ") ;
try {
//operations done on managed entities
//no transaction demarcation code is required here
dao.getEntityManager.commit();
}catch(Throwable xx){
}
}