简体   繁体   English

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

[英]Make transactionless EJB call inside a transaction

I'll try to describe the situation. 我将尽力描述这种情况。 We have a web service; 我们有一个网络服务; on each request web service starts a JTA transaction. 在每个请求Web服务上启动JTA事务。 It performs several database calls through XA datasource within that and calls some other web services (out of transaction context) and also makes a couple of remote EJB calls on other server. 它通过XA数据源执行多个数据库调用,并调用其他Web服务(不在事务上下文中),还在其他服务器上进行了几个远程EJB调用。

The problem is that container seems to try to involve EJB into transaction (and that seems logical), but in fact I want it to not particpate in that transaction as when it does participate in that transcation it always times out in the final commit phase, but when I exclude EJB call it works fine. 问题是容器似乎试图将EJB纳入事务中(这似乎是合乎逻辑的),但是实际上我希望它不参与该事务,因为当它确实参与该事务时,它总是在最后的提交阶段中超时,但是当我排除EJB调用时,它可以正常工作。

I cann't change EJB implementation and only control web service code. 我不能更改EJB实现,而只能控制Web服务代码。 So, my question is: how do I make an EJB call to transaction-aware EJB, but out of my JTA transaction, but still being in JTA transaction for other XA resourse? 因此,我的问题是:我如何在JTA事务之外,但仍在JTA事务中进行其他XA资源的情况下,对可感知事务的EJB进行EJB调用? I hope I made my question clear :). 我希望我的问题很清楚:)。

EDIT : Trying to make it more clear with pseudo-code example: 编辑 :试图使它与伪代码示例更加清晰:

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

You can create another bean with some appropriate transaction attribute. 您可以使用适当的事务属性创建另一个bean。 This bean can delegate all calls to the first bean. 该bean可以将所有调用委派给第一个bean。

Or you can invoke this ejb from another thread. 或者,您可以从另一个线程调用此ejb。

EJB transaction is declarative: for a given deployment of a given EJB, you specify its transaction semantics. EJB事务是声明性的:对于给定EJB的给定部署,请指定其事务语义。 The exact EJB can be deployed (under a different name, of course) and you can specify different requirements for that deployment. 可以部署确切的EJB(当然,可以使用其他名称),并且可以为该部署指定不同的需求。 This is assuming that (a) you at least have the jar for the ejb, and, (b) that the ejb in question is stand alone and doesn't have dependencies on other components, and (c) the developer of the ejb hasn't violated the idea of the declarative transactions and his bean works outside of a transaction context as well. 假设(a)您至少拥有ejb的jar,并且(b)所讨论的ejb是独立的,并且不依赖于其他组件,并且(c)ejb hasn的开发人员并没有违反声明式事务的想法,他的bean在事务上下文之外也可以工作。

You can create another method with the suitable tx attribute and then call it with through the self-injected proxy (pseudo-code): 您可以使用合适的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