在我们的Web应用程序中,我们有一个Facade EJB,它反过来调用多个EJB来执行业务功能。流程如下:
SLSB门面 - >调用ejb1,ejb2,ejb 3等 - >调用JPA层
在业务层的每个ejbs中,我使用@PersistenceContext注入实体管理器。
代码的简化版本如下:
@Stateless
public class facade{
@EJB
private EJB1 ejb1;
@EJB
private EJB2 ejb2;
@EJB ejb3;
private EJB3 ejb3;
public void performAction(..) {
// invoke method on ejb1
// invoke method on ejb2
// invoke method on ejb3
}
}
@Stateless
public class EJB1 implements IEjb1 {
@PersistenceContext(unitName = "pu")
private EntityManager entityManager;
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public xxxEntity insert(xxxEntity entity) throws AppException {
// code for persisting the entity
}
}
@Stateless
public class EJB2 implements IEjb2 {
@PersistenceContext(unitName = "pu")
private EntityManager entityManager;
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public yyyEntity insert(yyyEntity entity) throws AppException {
// code for persisting the entity
}
}
该应用程序部署在Glassfish上并使用JTA事务。由于这是容器管理的PC,是否会将相同的持久性上下文传播到所有EJB?它们是否会在同一个事务中运行(重用EJB1中启动的事务)?有没有办法验证所有EJB是否使用相同的事务(相同的事务ID?)
答案 0 :(得分:0)
默认情况下,所有ejbs(1,2,3)都将参与由facade ejb启动的同一个事务。您需要为它们定义不同的事务属性以使用不同的事务(例如REQIRES_NEW来创建新事务)。
如果你真的需要事务ID,你可以尝试将TransactionSynchronizationRegistry
注入你的bean
@Resource
TransactionSynchronizationRegistry registry;
// and then get key
...
registry.getTransactionKey()
请参阅TransactionSynchronizationRegistry和Container-Managed Transactions