Jpa 刷新和清除何时提交?

Jpa 刷新和清除何时提交?,jpa,transactions,eclipselink,jpa-2.0,jta,Jpa,Transactions,Eclipselink,Jpa 2.0,Jta,我正在使用JPA EclipseLink 2.0和Glassfish 3.1.2.2 我想知道我打电话后 em.flush() em.clear() 对象将立即提交到数据库。我的问题是我做了太多的事务,以至于我从内存中得到了。我希望通过刷新事务对象来避免这种情况 在刷新和清除之后,我看不到任何提交到数据库的直接实体,我只能在整个过程完成后看到它们,这告诉我这实际上不是提交 如果刷新和清除未提交: 1)它实际上做什么? 2)为什么我不再离开记忆? 请告诉我我是否正确: 在我的RAM中分配的对象

我正在使用JPA EclipseLink 2.0和Glassfish 3.1.2.2

我想知道我打电话后

em.flush() 
em.clear()
对象将立即提交到数据库。我的问题是我做了太多的事务,以至于我从内存中得到了
。我希望通过刷新事务对象来避免这种情况

在刷新和清除之后,我看不到任何提交到数据库的直接实体,我只能在整个过程完成后看到它们,这告诉我这实际上不是提交

如果刷新和清除未提交:

1)它实际上做什么?

2)为什么我不再离开记忆?

请告诉我我是否正确:


在我的RAM中分配的对象被发送到数据库,但更改尚未提交。这只意味着我清除了RAM,对象现在在DB服务器中,但事务尚未提交。

在JPA事务提交时,JPA正在自动进行刷新。您应该在第一个事务结束后立即在数据库中看到对象,而不仅仅是在整个流程结束后。检查是否确实要执行更多事务或仅执行一个。

实体在事务提交时同步到连接的数据库。如果只有n=1个正在进行的事务(此处:JTA/container managed),则在调用
EntityManager
实例上的
flush()
时,一个或多个实体上的更改会写入数据库

但是,只有在负责事务处理的容器(此处为Glassfish)正确执行事务后,更改才会变得“可见”。有关参考,请参阅。第7.6.1节(第294页)规定:

当在活动JTA事务的范围内调用容器管理的实体管理器时(特别是调用EntityManager接口的一个方法时),新的持久性上下文开始,并且当前没有与JTA事务关联的持久性上下文。创建持久性上下文,然后将其与JTA事务关联

当关联的JTA事务提交或回滚,并且由EntityManager管理的所有实体分离时,持久性上下文结束

在第3.2.4节(与数据库的同步)中,我们发现:

持久实体的状态在事务提交时同步到数据库

[……]

当事务处于活动状态时,允许持久性提供程序运行时在其他时间执行与数据库的同步。应用程序可以使用
flush
方法来强制执行同步

它适用于与持久性上下文关联的实体。
EntityManager
和Query setFlushMode方法可用于控制同步语义。第3.8.7节定义了
FlushModeType.AUTO
的效果。如果指定了
FlushModeType.COMMIT
,则在事务提交时将进行刷新;允许但不要求持久性提供程序在其他时间执行刷新。如果没有活动的事务,则持久性提供程序不得刷新到数据库

在您的场景中,容器(Glassfish)和/或应用程序很可能配置为
FlushModeType.COMMIT
(*1)。如果
FlushModeType.AUTO
已就位,则由持久性提供程序(EclipseLink)负责,“确保持久性上下文中所有实体状态的所有更新对查询处理可见,这些更新可能会影响查询结果。”(第3.8.7节,第122页)

相比之下,
clear()
方法本身并不提交任何内容。它只是将所有托管实体与当前持久性上下文分离,从而导致未刷新(提交)的实体上的任何更改丢失。有关参考,请参见第页。其中70%是链接的

关于
OutOfMemoryError
,很难说是什么原因导致了这种情况,因为您也没有提供太多细节。不过,我会:

  • 阅读JPA规范的上述章节
  • 检查您的环境是如何配置和配置的
  • 重新评估应用程序的编写/实现方式,可能会对其运行的容器的事务处理做出错误的假设
  • 与2相关,您可以检查您的
    persistence.xml
    是否配置了

    <property name="eclipselink.persistence-context.flush-mode" value="COMMIT" />
    
    
    
    并将其更改为
    AUTO
    ,以查看是否存在任何差异

    希望能有帮助

    脚注


    *1:但这是一个很好的猜测,因为您没有提供关于设置/环境的太多细节。

    对不起,我不是指多个事务。我的意思是在一次交易中插入多个信息。非常好的信息。我想解释为什么我对此感到好奇:我在使用JTA,但我也想控制事务何时提交。我发现,如果在托管BEAN上使用@TransactionManagement(TransactionManagementType.BEAN),然后使用UserTransaction,我就可以“手动”控制这一点(即使使用JTA)。不管怎样,这就是我问的问题,这是一个非常有趣和有用的答案。谢谢