提问者:小点点

CDI交易管理


我正在进行从JBoss Seam到CDI的迁移项目。以下是技术堆栈:

1)WildFly 8.2.0(以Weld为CDI提供商的CDI 1.2)

2)JSF 2.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>

并使用@PeristenceContext注解将EntityManager注入到DAO对象中。

我们对容器管理的事务使用@Transaction注释。

我的问题/理解如下。

有人能证实这一点吗,因为这对我来说是一个相对较新的领域。

1)据我了解,CDI通过@Transaction拦截器为CMT提供支持。哪个类/依赖项实际上实现了这个拦截器?我们需要在pom. xml中为此导入哪些工件?

2)由于使用了CMT,我们不需要划分任何事务,容器来管理它。我们只需要使用EntityManagerAPI来持久化Db中的更改。这种理解是否正确?

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

3)考虑使用上述配置执行的以下琐碎场景:

Component1. solemethod()-在事务内部运行并持久化一个实体(例如:User)并提交事务。在此之后,Component2被调用如下:
Component2.solemethod()-在转换内部运行,但实体User似乎没有处于托管状态,即em.包含(user)返回false。我必须再次合并这个实体以使其被管理或再次从持久存储重新加载

由于Seam使用会话范围的实体管理器,因此即使任何组件提交事务并在之后调用另一个组件,所有实体实例都保持托管状态(在持久上下文中)。但在CDI情况下,据我了解,这是由于“事务范围的实体管理器”而发生的。一旦事务提交,所有实体实例都变得分离。我们如何使用CDI实现与Seam相同的效果?


共2个答案

匿名用户

回答您的问题并澄清之前的答案,该答案仅针对Java6/CDI 1.0,而您正在使用JavaEE7/CDI 1.2

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

匿名用户

CDI不提供事务管理实现作为其规范的一部分。事务管理由程序员通过拦截器实现,拦截器将处理所有基础知识,如开始提交等。

通常EntityManager存在于事务的时间跨度内。在seam 2中,您有扩展的持久性上下文,因此它在多个请求中保持状态和附加到它的bean。CDI不提供这一点,而且由于可扩展性原因,它不建议这样做。如果你看看DeltaSpike,我强烈建议在从Seam2迁移到CDI的情况下,他们提供了延长EntityManager生命周期的选项,将其提升到会话范围,但他们也不推荐这种方法。

这里有DeltaSpike处理问题的文档:

https://deltaspike.apache.org/documentation/jpa.html#ExtendedPersistenceContexts

Deltaspike是一个很好的绑定解决方案,文档非常短,所以我会推荐它在你的情况下,除了它是由有接缝背景的人创建的,并提供开箱即用的事务管理。