CDI交易管理

时间:2015-07-06 18:19:49

标签: transactions cdi wildfly-8 jpa-2.1

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

1)WildFly 8.2.0(CDI 1.2,Weld作为CDI提供者)

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>

并使用@PersistenceContext注释将EntityManager注入DAO对象。

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

我的问题/理解如下。

任何人都可以证实这一点,因为这对我来说是一个相对较新的领域。

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

2)由于使用了CMT,我们不需要划分任何事务,容器将管理它。我们只需要使用EntityManager API来持久保存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.somemethod() - 在内部事务中运行并持久保存实体(例如:User)并提交事务。   在此之后,如下调用Component2:
  Component2.somemethod() - 在转换中运行,但实体User似乎不在托管状态em.contains(user)返回false。                 我必须再次合并此实体,以便再次从持久存储中管理或重新加载

由于Seam使用conversation-scoped entity manager,所以所有实体实例都保持托管状态(在持久化上下文中),即使任何组件提交事务并且之后调用另一个组件也是如此。 但在CDI案例中,我理解这是由于"transaction scoped entity manager"而发生的。事务提交后,所有实体实例都将分离。 我们如何使用CDI实现与Seam相同的效果?

2 个答案:

答案 0 :(得分:7)

在使用Java EE 7 / CDI 1.2时,回答您的问题并澄清以前只针对Java EE 6 / CDI 1.0的答案

  1. CDI没有实现交易,但JTA规范确实如此。是的JTA定义了拦截器绑定@Transactional,实现必须提供匹配的拦截器。正如你在WildFly下,你的问题的答案是在JBoss JTA实现:Narayana。您将找到@Transactional(Required)拦截器here。其他人也在同一个包中。
  2. 是的,您的理解是正确的。
  3. 扩展持久性上下文只能在EJB有状态会话bean中注入。在Java EE 7中,您可以尝试使用新的JPA 2.1 Unsyncrhonized mode(未在CDI中测试)。

答案 1 :(得分:2)

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

通常,EntityManager存在于事务的时间跨度内。在接缝2中,您已经扩展了持久性上下文,因此它可以跨多个请求保持状态和bean连接到它。 CDI没有提供,而且由于可伸缩性的原因,它不建议这样做。如果你看看DeltaSpike,我强烈建议在从Seam2迁移到CDI的情况下,它们提供了延长EntityManager寿命的选项,将其推广到会话范围,但他们也不建议采用这种方法。

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

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

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