繁体   English   中英

在事务内进行无事务的EJB调用

[英]Make transactionless EJB call inside a transaction

我将尽力描述这种情况。 我们有一个网络服务; 在每个请求Web服务上启动JTA事务。 它通过XA数据源执行多个数据库调用,并调用其他Web服务(不在事务上下文中),还在其他服务器上进行了几个远程EJB调用。

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

我不能更改EJB实现,而只能控制Web服务代码。 因此,我的问题是:我如何在JTA事务之外,但仍在JTA事务中进行其他XA资源的情况下,对可感知事务的EJB进行EJB调用? 我希望我的问题很清楚:)。

编辑 :试图使它与伪代码示例更加清晰:

// 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();

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

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

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

您可以使用合适的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();
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM