在 TomEE 中(最好使用容器管理的事务)我想做一个子请求并在我当前的请求中使用它的输出,但两者必须是同一事务的一部分。欢迎所有(甚至是疯狂的想法,但最好只使用标准 API 而不是 TomEE 特定的)如何做到这一点。
最佳答案
这个 stackoverflow 问题提供了一个提示来回答我的问题:Acessing Remote/Local Session Beans
感谢一位同事,我通过以下方式将其与 TomEE 一起使用:
结构是有两个 web 应用程序和一个接口(interface) jar:
- AppA。公开调用无状态的 RESTfull Web 服务 重用来自 AppB 的无状态 session bean 的 session bean (BeanA)。 这是作为 WAR 构建的。
- 应用程序 B。公开无状态 session bean BeanB。这是作为 WAR 构建的。
- AppBItf.包含本地接口(interface) BeanB的。这是构建为 JAR,将在 AppA 之间共享 和 AppB。
AppA 的内容
在 AppA 中,我们拥有三样东西:REST 服务、bean 及其本地接口(interface)。 RestService.java
import javax.ejb.EJB;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.core.Response;
@Path("/RestService/")
public class RestService
{
@EJB
BeanALocal bean;
@GET
@Path("/doInTransaction")
public Response doInTransaction() {
return Response.ok().entity("Transaction result: " + bean.doInTransaction()).build();
}
}
BeanA.java
import javax.annotation.Resource;
import javax.ejb.EJB;
import javax.ejb.LocalBean;
import javax.ejb.Stateless;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.transaction.TransactionSynchronizationRegistry;
import BeanBLocal;
@Stateless
@LocalBean
public class BeanA implements BeanALocal
{
@EJB
BeanBLocal beanB;
@Resource
TransactionSynchronizationRegistry txReg;
@Override
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public String doInTransaction() {
return "Transaction: " + txReg.getTransactionKey() + "; BeanB: " + beanB.doInTransaction();
}
}
BeanALLocal.java
import javax.ejb.Local;
@Local
public interface BeanALocal {
String doInTransaction();
}
AppB的内容
这仅包含 bean(其本地接口(interface)在 AppBItf 中定义):
BeanB.java
import javax.annotation.Resource;
import javax.ejb.LocalBean;
import javax.ejb.Stateless;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.transaction.TransactionSynchronizationRegistry;
@Stateless
@LocalBean
public class BeanB implements BeanBLocal
{
@Resource
TransactionSynchronizationRegistry txReg;
@Override
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public String doInTransaction() {
return "BeanB: Transaction: " + txReg.getTransactionKey();
}
}
AppBItf 的内容
这只包含 BeanB 的本地接口(interface):
BeanBLocal.java
import javax.ejb.Local;
@Local
public interface BeanBLocal {
String doInTransaction();
}
部署
这两个WAR(AppA.war和AppB.war)可以简单地部署到webapps,但是JAR(AppBItf)需要添加到公共(public)类加载器(common.loader)。
结果
在上面的代码中,BeanB 被注解为 TransactionAttributeType.REQUIRED。调用 REST 服务(即在 http://localhost:8080/AppA/RestService/doInTransaction 上执行 GET)会导致以下输出:
[Xid:globalId=1000000047544d4944,length=64,branchId=0,length=64];
[Xid:globalId=1000000047544d4944,length=64,branchId=0,length=64]
注意第一个和第二个事务ID是一样的,所以BeanA的事务被BeanB复用了。这就是我所需要的。
当我将注释更改为 TransactionAttributeType.REQUIRES_NEW 时,容器会自动为 BeanB 启动一个新事务:
[Xid:globalId=1000000047544d4944,length=64,branchId=0,length=64];
[Xid:globalId=2000000047544d4944,length=64,branchId=0,length=64]
第一笔交易ID以1开头,第二笔交易ID以2开头。
关于tomcat - 如何在 TomEE 中的同一事务中执行子请求?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32226242/