HIbernate commit()和flush()

我GOOGLE了很多,并了解org.hibernate.Transaction.commit()org.hibernate.Session.flush()很多,知道每个方法的目的,但仍然有一个问题。

手工调用org.hibernate.Session.flush()方法是不是很好? 正如org.hibernate.Session文档中所说,

必须在工作单元结束时调用,在提交事务并closures会话之前(取决于flush-mode,Transaction.commit()调用此方法)。

你能解释一下,如果org.hibernate.Transaction.commit()会自动调用org.hibernate.Session.flush()的目的吗?

谢谢!

在“hibernate手册”中可以看到这个例子

 Session session = sessionFactory.openSession(); Transaction tx = session.beginTransaction(); for ( int i=0; i<100000; i++ ) { Customer customer = new Customer(.....); session.save(customer); if ( i % 20 == 0 ) { //20, same as the JDBC batch size //flush a batch of inserts and release memory: session.flush(); session.clear(); } } tx.commit(); session.close(); 

没有对flush方法的调用,你的第一级caching会抛出一个OutOfMemoryExceptionexception

你也可以看看这个post关于冲洗

显式刷新的一个常见情况是当你创build一个新的持久化实体时,你希望它有一个人为的主键生成并分配给它,以便以后在同一个事务中使用它。 在这种情况下调用flush会导致你的实体被赋予一个id。

另一种情况是,如果第一级caching中有很多东西,并且您想定期清除它(为了减lesscaching使用的内存量),但是您仍然想要将整个事件放在一起。 Aleksei的回答涵盖了这个情况(从我+1)。

flush()会将你的数据库与保存在内存中的对象/对象的当前状态同步,但是它不提交事务。 所以,如果在调用flush()之后得到任何exception,那么事务将被回滚。 你可以使用flush()来同步你的数据库和一小块数据,而不是一次使用commit()提交一个大的数据,并面临得到一个Out Of Memory Exception的风险。

commit()将使存储在数据库中的数据永久。 一旦commit()成功,你就无法回滚你的事务。

冲洗(); Flushing是同步持久化存储和持久化状态的过程,它将在正在运行的事务中更新或插入到表中,但不能提交这些更改。

您需要在批处理中刷新,否则可能会发生OutOfMemoryException。

承诺(); 提交将使数据库提交。当你有一个持久化对象,并且你改变一个值时,它就变成了肮脏的,而且hibernate需要把这些改变刷新到你的持久层。所以你应该提交,但是它也结束了工作单元。 器transaction.commit()

默认情况下,flush模式是AUTO,这意味着:“在查询执行之前会话有时被刷新以确保查询永不返回陈旧状态”,但是当提交更改时,大部分时间会话都被刷新。 手动调用flush方法在使用FlushMode = MANUAL时是有用的,或者您想进行某种优化。 但我从来没有这样做,所以我不能给你实际的build议。

session.flush()是同步方法,意思是将数据顺序地插入到数据库中。如果我们使用这个方法,数据将不会存储在数据库中,而是存储在caching中,如果有任何exception会在中间升起,我们可以处理它。 但是commit()会将数据存储在数据库中,如果我们存储的数据量较多的话,可能会有机会出现内存exception,就像在JDBC程序中保存点主题