我想确保理解交易传播,请帮忙。
假设我们有一个无状态的 EJB_A ,它暴露了应用程序层的服务。
它使用本地无状态 EJB_B , EJB_C , 他们都使用托管 EntityManager 的容器 EJB_B 和 EJB_C 使用其他方法。
如果我理解了正确的事情,每个EJB都会将EntityManager自身归为管理相同的持久性单元。
假设客户端请求上的 EJB_A 使用bot EJB_B和EJB_C的方法来创建事务,例如:
@Stateless(name = "myejb")
public class EJB_A implements Interface_EJB_A
{
@EJB
private EJB_B ejb_b;
@EJB
private EJB_C ejb_c;
public String method()
{
ejb_b.call();
ejb_c.call();
}
...
}
如何在EJB_C中注入实体管理器,知道正在进行交易 如果它对EJB_B中注入的EntityManager的存在一无所知?
正是这个容器之王增添了魔力,我很难掌握......
答案 0 :(得分:0)
容器内部使用ThreadLocal变量来存储事务。并且实体管理器使用的持久性上下文与此事务同步。因此,EJB A,B和C完成的工作都链接到相同的持久化上下文,并在同一事务中完成。
规格说:
默认情况下,容器管理的持久性上下文是SynchronizationType.SYNCHRONIZED,并自动加入当前事务。
[...]
应用程序可以通过在JNDI名称空间中注入或直接查找来获取具有事务范围持久性上下文的容器管理实体管理器。实体管理器的持久性上下文类型是默认的或定义为PersistenceContextType.TRANSACTION。
当在活动JTA事务的范围内调用容器管理的实体管理器[82]时,新的持久性上下文开始,并且当前没有与JTA事务关联的持久性上下文。创建持久性上下文,然后与JTA事务关联。
[...]
如7.1节所述,单个持久化上下文可以对应于一个或多个JTA实体管理器实例(全部与同一实体管理器工厂[84]相关联)。 随着JTA事务的传播,持久化上下文在实体管理器实例中传播。