事务范围的持久性上下文和扩展持久性上下文之间的区别是什么?
答案 0 :(得分:44)
JSR-220 Enterprise JavaBeans 3.0规范中明确解释了差异:
5.6容器管理的持久性上下文
(...)
容器管理的持久性 上下文可以定义为具有 一个限定为单一的生命周期 交易或延长寿命 跨越多个交易, 取决于
PersistenceContextType
就是这样 在其EntityManager
时指定 创建。本规范涉及 这样的持久性语境如 事务范围的持久性上下文和扩展持久性 上下文。(...)
5.6.1容器管理的事务范围持久化上下文
申请可以获得 容器管理的实体管理器 事务范围的持久化上下文 绑定到JTA事务 在JNDI中注入或直接查找 命名空间。持久化上下文 实体管理器的类型是 违约或定义为
PersistenceContextType.TRANSACTION
。新的持久化上下文从何时开始 容器管理的实体管理器 在范围内调用 [36] 一个活跃的JTA交易,和 没有当前的持久性 上下文已经与 JTA交易。坚持不懈 创建上下文然后关联 与JTA交易。
持久化上下文在结束时结束 关联的JTA事务提交或 回滚,以及所有实体 由EntityManager管理成为 分离。
如果调用实体管理器 在交易范围之外, 从数据库加载的任何实体 将立即脱离 方法调用的结束。
5.6.2容器管理的扩展持久化上下文
容器管理的扩展 持久化上下文只能是 在一个范围内发起的 有状态会话bean。它存在于 有状态的地方 会话bean声明了一个 依赖于实体经理 输入
PersistenceContextType.EXTENDED
是创造的,据说是受约束的 有状态会话bean。该 依赖于扩展持久性 上下文是通过PersistenceContext
注释或 持久性 - context-ref部署 描述符元素。持久性上下文关闭
@Remove
时的容器 有状态会话bean的方法 完成(或有状态会话 否则会破坏bean实例。(...)
答案 1 :(得分:7)
有许多细节要尊重......但为了保持简短,我记得这样的差异:
简而言之:当调用事务范围bean上的方法时,容器将自动启动一个事务,并为您创建一个新的持久化上下文。当方法结束时,事务结束并且持久化上下文将关闭,您的实体将变为分离。
好处:此行为是无状态的,您不需要在代码中进行太多维护,并使您的EntityManager线程安全。
简而言之:只能用于有状态会话bean,并且与bean的生命周期相关联。持久化上下文可以在多个事务中产生,这意味着扩展bean中的方法共享相同的持久化上下文。
好处:完美实现与客户的对话风格互动。您的客户端调用几个bean方法来告诉您的bean您需要知道的所有信息,并在对话结束时将所有内容保存到您的数据库中。
事务传播:假设事务范围bean的默认TransactionAttributes有两个方法A和B.
如果在方法A中调用方法B,则可以将A持久化上下文传播到B.这样,方法B甚至可以访问由A创建/更改的非持久化实体,因为它们仍然可以被管理通过B现在可以访问的持久性上下文。
从扩展到事务范围的事务传播:您可以通过调用事务的方法将扩展bean的持久性上下文传播到事务范围的bean - 来自扩展bean的scoped bean。使用默认事务属性(REQUIRED
),事务范围的bean将重用扩展bean的现有活动持久性上下文。
从事务范围扩展到扩展的事务传播:然而另一种方式并不直观,因为扩展的持久化上下文总是试图使自己成为活动的持久化上下文。您必须使用@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
更改扩展bean的默认事务属性。这将在扩展bean方法启动之前挂起任何活动事务(与持久性上下文相关联)。
答案 2 :(得分:5)
事务范围持久化上下文
顾名思义,事务范围的持久化上下文与生命周期相关联 交易。它在事务期间由容器创建,并在事务时关闭 完成。
事务范围的实体管理器负责创建事务范围 需要时自动持久化上下文。我们只在需要时说,因为交易已经完成 持久化上下文创建是懒惰的。
实体管理器将仅创建持久性上下文 在实体管理器上调用方法时以及没有可用的持久性上下文时。
扩展持久性上下文
扩展持久化上下文的生命周期与它绑定的有状态会话bean相关联。
与为每个实体创建新的持久性上下文的事务范围实体管理器不同 事务,有状态会话bean的扩展实体管理器始终使用相同的持久性 上下文。
有状态会话bean与单个扩展持久性上下文相关联 创建bean实例时创建,并在删除bean实例时关闭。这有 对扩展持久性的关联和传播特性的影响 上下文。
答案 3 :(得分:0)
@PersistenceContext(type = PersistenceContextType.TRANSACTION)
如果我们仅编写@PersistenceContext
,则与编写上面的语句一样好。 紧急刷新(保存)对数据库的更改。
@PersistenceContext(type = PersistenceContextType.EXTENDED)
在这里,这意味着不要急于刷新(保存)对数据库的更改,而是等待下一个活动事务启动或等待强制提交触发
看看https://www.byteslounge.com/tutorials/jpa-extended-persistence-context