jakarta-ee - 在托管事务期间关闭远程EJB连接

原文 标签 jakarta-ee ejb java-ee-6 distributed-transactions initial-context

我有以下情况:


客户端正在调用无状态本地EJB-托管事务从此调用开始
本地EJB构建InitialContext并查找远程EJB
本地EJB在远程EJB上调用方法
本地EJB关闭上下文并连接到远程EJB
容器尝试提交事务


无法提交分布式事务,因为无法连接到参与事务的远程EJB的连接,因为它的连接已关闭。

我的问题是:当已有事务处于活动状态时,是否可以使用远程EJB调用?我应该如何关闭用于查找远程EJB的上下文?

以下伪代码说明了我的问题:

@Stateless
public class LocalEjb {

  public void localEJBMethod() {
    //transaction starts before this method execution

    Context ctx = //create initial context
    RemoteEjb remoteEjb = (RemoteEjb) ctx.lookup("jndi name");
    remoteEjb.remoteMethod(); //remote EJB takes part in distributed transaction
    ctx.close();    

    //error occurrs when container tries to commit distributed transaction after
    //this method returns
  }
}


public class ClientClass { //a CDI component, for example
    @EJB
    private LocalEjb localEjb;

    public void clientMethod() {
        localEjb.localEjbMethod();
    }
}

最佳答案

事务将起作用,因为应用程序服务器使用XA(分布式)事务。

摆脱ctx.close()

它实际上并没有关闭与远程ejb(由动态代理对象处理)的连接,而是要关闭对JNDI上下文的访问,该上下文包含事务管理器的句柄。

还要记住,您需要让容器知道您正在使用另一个EJB。所有容器管理的对象都需要向应用程序服务器声明其资源需求(ejb,数据源等)。在关于您的示例中,您将声明放在ejb-jar.xml中。

您可能考虑对远程EJB使用@EJB批注,而不是使用显式查找。这将向应用程序服务器声明资源使用,并将为您管理引用。

相关文章:

java - 使用功能丰富但兼容的库迁移到新版本的JSF

jakarta-ee - 为什么具有bean管理的事务的EJB bean充当“事务障碍”?

java - 创建异常的成本与记录异常的成本

java - 可以使用@Resource在EJB3.0中注入基元吗?

java - 登录后如何正确注销Java EE 6 Web应用程序

java - 单击超链接时调用servlet

java - 在Java EE服务器中打包EJB

java - EJB异常-尝试使用具有空Session的间接遍历关系。

java - 如何在servlet 3.0的web.xml-less中定义<welcome-file-list>和<error-page>?

java - Java性能前端:引用for循环