在TomEE中(最好使用容器管理的事务)我想做一个子请求并在我当前的请求中使用它的输出,但两者都必须是同一事务的一部分。所有(甚至是疯狂的想法,但最好只使用标准的API而不是TomEE特定的)欢迎如何做到这一点。
答案 0 :(得分:0)
此stackoverflow问题提供了一个提示来回答我的问题:Acessing Remote/Local Session Beans
感谢一位同事,我通过以下方式与TomEE合作:
结构是拥有两个Web应用程序和一个接口jar:
AppA的内容
在AppA中,我们有三件事:REST服务,bean及其本地接口。 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();
}
}
BeanALocal.java
import javax.ejb.Local;
@Local
public interface BeanALocal {
String doInTransaction();
}
AppB的内容
这只包含bean(其本地接口在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的本地接口:
BeanBLocal.java
import javax.ejb.Local;
@Local
public interface BeanBLocal {
String doInTransaction();
}
部署
可以简单地将两个WAR(AppA.war和AppB.war)部署到webapps,但需要将JAR(AppBItf)添加到公共类加载器(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是相同的,因此BeanB的事务将由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开头,而第二笔以2开头。