Transactions CDI事务管理

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="

我正在做一个从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="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

  • CDI不实现事务,但JTA规范实现。是,JTA定义了拦截器绑定
    @Transactional
    ,实现必须提供匹配的拦截器。在WildFly下,您的问题的答案在JBoss JTA实现中:Narayana。您将找到
    @事务(必需)
    拦截器。其他的都在同一个包裹里
  • 是的,你的理解是正确的
  • 扩展持久性上下文只能在EJB有状态会话bean中注入。在JavaEE7中,您可以尝试使用新的(未在CDI中测试)

  • 关于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){
        }
        }