【问题标题】:Perform work in a XA transaction在 XA 事务中执行工作
【发布时间】:2012-11-03 13:59:58
【问题描述】:

我有一种情况需要在全局 tx 中执行一些工作。

出于这个原因,我在我的 persistence.xml 中定义了以下 PersistenceUnit 来获得一个 jta entityManager。

<persistence-unit name="resubEclipselink" transaction-type="JTA">
    <jta-data-source>jdbc/XADataSource</jta-data-source>
    ...
</persistence-unit>

现在为了坚持,我尝试按照以下 #1 进行:

    if(isXA()){
        mXAEntityManager.persist(entity);
        mXAEntityManager.flush(); 
    }

由于异常而失败

javax.persistence.TransactionRequiredException: 
Exception Description: No transaction is currently active
    at       
org.eclipse.persistence.internal.jpa.transaction.EntityTransactionWrapper.throwCheckTransactionFailedException(EntityTransactionWrapper.java:113)

当我在继续之前开始用户事务时,我得到了同样的原因。

所以我尝试了另一种方法#2:

// get the transactional unit of work or null.
UnitOfWork uow = mEntityManager.getUnitOfWork();
    uow.registerObject(entity);
uow.writeChanges(); 
uow.commit();           

这种方法可行,但我不确定这是否是正确的方法。

如果有人可以帮助我解决为什么在第一种情况下无法正常工作以及第二种方法是否可行,我将不胜感激?

【问题讨论】:

    标签: jpa-2.0 eclipselink jta


    【解决方案1】:

    第一种方法应该可行,配置设置可能缺少告诉 Eclipselink 事务。检查您是否指定了此处描述的目标服务器属性 http://eclipse.org/eclipselink/documentation/2.4/jpa/extensions/p_target_server.htm 因为这将用于获取事务管理器并注册活动事务。

    一旦在事务中正确注册,就不需要直接在 UnitOfWork 上调用 commit。

    【讨论】:

      【解决方案2】:

      我假设您之前在您的代码中以 SE 方式实例化了 mXAEntityManager,如下所示:

      EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("resubEclipselink");

      EntityManager mXAEntityManager = entityManagerFactory.createEntityManager();

      这在部署在应用程序服务器中的 EE 应用程序中不起作用。您应该像这样用依赖注入替换这两行:

      @PersistenceContext(unitName = "resubEclipselink")

      EntityManager mXAEntityManager;

      这样您就可以让容器注入一个持久性上下文 (mXAEntityManager) 以及您需要的所有事务管理。因此,不再需要 flush() no begin() no commit() 调用,只要您不弄乱已经设置为这样的默认值:

      @PersistenceContext(unitName = "resubEclipselink", type= PersistenceContextType.TRANSACTION)

      EntityManager mXAEntityManager;

      以及已经为您的会话 bean 设置的另一个默认值,如下所示:

      @TransactionAttribute(TransactionAttributeType.REQUIRED)

      请记住,这些默认设置使得开发 EE 应用程序遵循“异常配置”范式。

      【讨论】:

      • 感谢您的解释,这正是我为获得 entityManager 所做的事情。现在我明白了,我可能需要一个容器管理的实体管理器,并且应该按照您建议的方式获取它。但不幸的是,我的场景以某种方式运行,我需要根据其他一些条件来决定事务边界。此外,我通过一个不在我控制范围内的外观 api 进行调用,因此通过会话 bean 注入对我来说可能不太可行。
      【解决方案3】:

      我的场景以某种方式运行,我需要根据其他一些条件来决定事务边界。

      所以基本上我需要让我的应用程序管理的实体管理器登记到全局 tx 并执行一些工作单元作为全局 tx 的一部分。所以我实际上得到了一个实体管理器并将其设置为使用 ExternalTransactionController。

                  if(isXA){
                          this.mEntityManager = JpaHelper.getEntityManager(Persistence.createEntityManagerFactory(XA_PU).
      
                                                  createEntityManager());
      
                          this.mServerSession = this.mEntityManager.getServerSession();
                          this.mServerSession.getLogin().setUsesExternalTransactionController(true);
                          this.mServerSession.getLogin().setUsesExternalConnectionPooling(true);
                  }else{
                         this.mEntityManager = JpaHelper.getEntityManager(Persistence.createEntityManagerFactory(RESORUCE_LOCAL_PU).
                                                                                                                                  createEntityManager());
      
                          this.mEntityTransaction = this.mEntityManager.getTransaction();
                          this.mServerSession = this.mEntityManager.getServerSession();
                  }
      

      然后获取并执行工作单元...

        // get the transactional unit of work or null.
        UnitOfWork uow = mEntityManager.getUnitOfWork();
      
        // resource-local em
        if(uow == null){
                mEntityTransaction.begin(); 
                mEntityManager.persist(entity); 
                mEntityTransaction.commit();
        }else{                  
                uow.registerObject(entity);
                uow.writeChanges(); 
                uow.commit();                   
        }
      

      正如我之前提到的,我对这种方法不太有信心,因此如果有人可以对此进行审查并让我知道这种方法是否存在一些缺陷,我将不胜感激......

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-12-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多