ThinkSSL🔒 一键申购 5分钟快速签发 30天无理由退款 购买更放心 广告
# 10.10\. Session刷出(flush) 每间隔一段时间,`Session`会执行一些必需的SQL语句来把内存中的对象的状态同步到JDBC连接中。这个过程被称为_刷出(flush)_,默认会在下面的时间点执行: * 在某些查询执行之前 * 在调用`org.hibernate.Transaction.commit()`的时候 * 在调用`Session.flush()`的时候 涉及的SQL语句会按照下面的顺序发出执行: 1. 所有对实体进行插入的语句,其顺序按照对象执行`Session.save()`的时间顺序 2. 所有对实体进行更新的语句 3. 所有进行集合删除的语句 4. 所有对集合元素进行删除,更新或者插入的语句 5. 所有进行集合插入的语句 6. 所有对实体进行删除的语句,其顺序按照对象执行`Session.delete()`的时间顺序 (有一个例外是,如果对象使用`native`方式来生成ID(持久化标识)的话,它们一执行save就会被插入。) 除非你明确地发出了`flush()`指令,关于Session_何时_会执行这些JDBC调用是完全无法保证的,只能保证它们执行的前后顺序。 当然,Hibernate保证,`Query.list(..)`绝对不会返回已经失效的数据,也不会返回错误数据。 也可以改变默认的设置,来让刷出(flush)操作发生的不那么频繁。 `FlushMode`类定义了三种不同的方式。 仅在提交时刷出(仅当Hibernate的`Transaction` API被使用时有效), 按照刚才说的方式刷出, 以及除非明确使用`flush()`否则从不刷出。 最后一种模式对于那些需要长时间保持`Session`为打开或者断线状态的长时间运行的工作单元很有用。 (参见 [第 11.3.2 节 “扩展周期的session和自动版本化”](../Text/pr01_split_000.html#transactions-optimistic-longsession "11.3.2\. 扩展周期的session和自动版本化")). ``` sess = sf.openSession(); Transaction tx = sess.beginTransaction(); sess.setFlushMode(FlushMode.COMMIT); // allow queries to return stale state Cat izi = (Cat) sess.load(Cat.class, id); izi.setName(iznizi); // might return stale data sess.find("from Cat as cat left outer join cat.kittens kitten"); // change to izi is not flushed! ... tx.commit(); // flush occurs sess.close(); ``` 刷出(flush)期间,可能会抛出异常。(例如一个DML操作违反了约束) 异常处理涉及到对Hibernate事务性行为的理解,因此我们将在[第 11 章 _事务和并发_](../Text/pr01_split_000.html "第 11 章 事务和并发")中讨论。