实体被同步到连接的数据库在事务提交时间。如果你只有N = 1个正在进行中的事务(此处:JTA /容器管理),对一个或多个实体的变化被写入到数据库调用flush()
在EntityManager
实例的时刻。
然而,变化成为“看得见”后,方可交易已经由容器(这里:Glassfish的)被正确执行,负责事务处理。有关参考,请参阅。的JPA Spec 2.0 7.6.1(第294)部分,其定义了:
新持久上下文开始当容器管理实体管理器被调用(具体而言,当EntityManager接口的方法之一是在一个JTA事务的范围调用),并且存在已经与JTA事务关联没有电流持久性上下文。持久化上下文被创建并且与JTA事务关联。
当关联的JTA事务提交或回滚时,持久性上下文结束,并且由EntityManager管理的所有实体都被分离。
在第3.2节。在JPA Spec 2.0的4(同步到数据库),我们发现:
持久化实体的状态在交易同步到数据库提交。
[..]
持久化提供者运行时被允许执行同步在其他时间数据库以及当事务是活动的。 flush
方法可以被应用程序使用来同步force。
它适用于与持久性上下文相关联的实体。可以使用EntityManager
和Query setFlushMode方法来控制同步语义。第3.8.7节定义了FlushModeType.AUTO
的效果。如果指定了FlushModeType.COMMIT
,则在事务提交时会发生刷新;在其他时间,持久性提供者被允许(但不是必需)执行刷新。如果没有事务处于活动状态,则持久性提供程序不得刷新到数据库。
最有可能在您的情况下,容器(Glassfish)和/或您的应用程序配置为FlushModeType.COMMIT
(* 1)。在FlushModeType.AUTO
的情况下,它由持久性提供者(EclipseLink)决定,“负责确保持久性上下文中可能影响查询结果的所有实体的状态的所有更新对于处理查询“(第3.8.7节,第122页)
相比之下,clear()
方法本身并没有提交任何东西。它只是将当前持久化上下文中的所有管理实体分开,从而导致未刷新(提交)的实体发生任何更改而丢失。有关参考资料,请参见p。 70链接JPA Spec。
关于OutOfMemoryError
,很难说在什么情况下导致了这种情况,因为您没有提供太多细节。不过,我想:
- 阅读JPA规范
- 检查你的环境是如何配置与前述部分
- 重新评估你的应用程序是如何采写/实施,对交易处理可能使错误的假设它在运行的容器。
相关的2,你可以检查你的persistence.xml
是否配置
<property name="eclipselink.persistence-context.flush-mode" value="COMMIT" />
并将其更改为AUTO
以查看是否有任何区别。
希望它有帮助。
脚注
* 1:但是,这是一个很好的猜测,因为你没有提供你的设置/环境的细节。
伟大的信息。我想解释一下为什么我对此感到好奇:我正在使用JTA,但我也想控制事务提交的时间。我发现的是,如果我在托管bean上使用@TransactionManagement(TransactionManagementType.BEAN),然后使用UserTransaction,则可以“手动”控制此操作(即使使用JTA)。任何方式,这是我问,这是一个非常有趣和有用的答案。谢谢。 –