在事务内进行无事务 EJB 调用
我将尝试描述一下情况。我们有网络服务;对于每个请求,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();
I'll try to describe the situation. We have a web service; on each request web service starts a JTA transaction. 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.
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.
I cann't change EJB implementation and only control web service code. 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? 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();
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您可以使用一些适当的事务属性创建另一个 bean。该 bean 可以将所有调用委托给第一个 bean。
或者您可以从另一个线程调用此 ejb。
You can create another bean with some appropriate transaction attribute. This bean can delegate all calls to the first bean.
Or you can invoke this ejb from another thread.
EJB 事务是声明性的:对于给定 EJB 的给定部署,您可以指定其事务语义。可以部署确切的 EJB(当然可以使用不同的名称),并且您可以为该部署指定不同的要求。这是假设 (a) 您至少拥有 ejb 的 jar,并且 (b) 相关的 ejb 是独立的并且不依赖于其他组件,并且 (c) ejb 的开发人员没有没有违反声明性事务的思想,并且他的 bean 也可以在事务上下文之外工作。
EJB transaction is declarative: for a given deployment of a given EJB, you specify its transaction semantics. The exact EJB can be deployed (under a different name, of course) and you can specify different requirements for that deployment. 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.
您可以使用合适的 tx 属性创建另一个方法,然后通过自注入代理(伪代码)调用它:
You can create another method with the suitable tx attribute and then call it with through the self-injected proxy (pseudo-code):