session flush在commit以前默认都会执行, 也能够手动执行,他主要作了两件事:
1) 清理缓存。
2) 执行SQL。 spring
flush: Session 按照缓存中对象属性变化来同步更新数据库。sql
默认状况下,Session 会在如下状况下调用 flush:数据库
1. 直接调用 session.flush。缓存
2. 当应用调用Transaction.commit() 时, 会先调用 flush, 而后再向数据路提交。session
3. 在作查询时(HQL, Criteria),若是缓存中持久化对象的属性发生变化,会先 flush 缓存,以保证查询结果是最新的数据。spa
flush 缓存的例外状况:若是对象使用native 生成器生成 ID 时,在当调用session.save() 去保存对象时, 会直接向数据库插入该实体的 insert 语句。hibernate
flush 的五种 FlushModel :对象
一、NEVEL:已经废弃了,被MANUAL取代了
2 MANUAL:
若是FlushMode是MANUAL或NEVEL,在操做过程当中Hibernate会将事务设置为readonly,因此在增长、删除或修改操做过程当中会出现以下错误
org.springframework.dao.InvalidDataAccessApiUsageException: Write operations are not allowed in read-only mode (FlushMode.NEVER) - turn your Session into FlushMode.AUTO or remove 'readOnly' marker from transaction definition;
解决办法:配置事务, Spring会读取事务中的各类配置来覆盖hibernate的session中的FlushMode;
3 AUTO
设置成auto以后,当程序进行查询、提交事务或者调用session.flush()的时候,都会使缓存和数据库进行同步,也就是刷新数据库
4 COMMIT
提交事务或者session.flush()时,刷新数据库;查询不刷新
5 ALWAYS:
每次进行查询、提交事务、session.flush()的时候都会刷数据库事务
ALWAYS和AUTO的区别:当hibernate缓存中的对象被改动以后,会被标记为脏数据(即与数据库不一样步了)。当 session设置为FlushMode.AUTO时,hibernate在进行查询的时候会判断缓存中的数据是否为脏数据,是则刷数据库,不是则不刷,而always是直接刷新,不进行任何判断。很显然auto比always要高效得多。rem
若是session 中的某个类的属性发生了改变,使用flush() 方式,去更改数据库中的记录,使其和改变后的session 中的对象一致
session.commit 和 session.flush 区别:
session.flush: 执行 一列 sql,可是不提交
session.commit: 会先执行 flush,而后提交事务,提交事务意味着对数据库的操做永久保存,不可rollback。