【问题标题】:Make transactionless EJB call inside a transaction在事务中进行无事务 EJB 调用
【发布时间】:2009-09-04 19:57:30
【问题描述】:

我会试着描述一下情况。我们有一个网络服务;在每个请求 Web 服务启动一个 JTA 事务。它通过其中的 XA 数据源执行几个数据库调用,并调用一些其他 Web 服务(在事务上下文之外),还在其他服务器上进行几个远程 EJB 调用。

问题是容器似乎试图将 EJB 纳入事务(这似乎合乎逻辑),但实际上我希望它不参与该事务,因为当它确实参与该事务时,它总是在最终超时提交阶段,但是当我排除 EJB 调用时它工作正常。

我无法更改 EJB 实现,只能控制 Web 服务代码。所以,我的问题是:我如何对事务感知 EJB 进行 EJB 调用,但在我的 JTA 事务之外,但仍处于其他 XA 资源的 JTA 事务中?我希望我把我的问题说清楚了:)。

编辑:尝试通过伪代码示例使其更清晰:

// Begin transaction
UserTransaction tx = (UserTransaction) ctx.lookup(USER_TRANSACTION);
tx.begin();

// Do some database operations on XA datasource

// Call remote EJB which has transcation attribute set to 'Supports'
AccountInfo account = accountEjb.getAccountInfo(userId, accountId); // <-- Is it possible to make this to be not be part of user transction?

// Do some more database operations on XA datasource

// Commit transaction
tx.commit();

【问题讨论】:

  • 为什么不增加超时时间?
  • 因为问题不在于超时,所有调用都在毫秒内完成,但是当事务最终提交时它超时,如果从调用序列中删除 ejb 调用,它会提交好的。所以,我认为它实际上必须与服务器间通信做一些事情,但不是超时的值。

标签: java jakarta-ee transactions ejb jta


【解决方案1】:

您可以使用一些适当的事务属性创建另一个 bean。这个 bean 可以将所有调用委托给第一个 bean。

或者您可以从另一个线程调用此 ejb。

【讨论】:

    【解决方案2】:

    EJB 事务是声明性的:对于给定 EJB 的给定部署,您可以指定其事务语义。可以部署确切的 EJB(当然,使用不同的名称),您可以为该部署指定不同的要求。这是假设(a)您至少有 ejb 的 jar,并且,(b)有问题的 ejb 是独立的,并且不依赖于其他组件,并且(c)ejb 的开发人员没有'没有违反声明性事务的想法,并且他的 bean 也在事务上下文之外工作。

    【讨论】:

    • 我无法控制 EJB,但我知道它的事务属性设置为“支持”,并且我还对该 EJB 进行了独立(容器外)调用,没有任何问题。此外,EJB 和我的 Web 服务部署在不同的服务器上,我也无法更改。
    【解决方案3】:

    您可以创建另一个具有合适 tx 属性的方法,然后通过自注入代理(伪代码)调用它:

    @Stateless
    public class LocalEJB1 {
    
        @EJB
        private LocalEJB1 localEJB1;
    
        @EJB
        private AccountEJB accountEjb;
    
        @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
        public AccountInfo callNonTx() { 
            return accountEjb.getAccountInfo(userId, accountId); 
        }
    
        public void yourCurrentMethod() {
            // Begin transaction
            UserTransaction tx = (UserTransaction) ctx.lookup(USER_TRANSACTION);
            tx.begin();
    
            AccountInfo account = localEJB1.callNonTx();
            // Do some more database operations on XA datasource
    
            // Commit transaction
            tx.commit();
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-10-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-12
      • 2017-09-14
      相关资源
      最近更新 更多