介绍
在我之前的文章中,我介绍了实体状态转换 对象关系映射范例。
当刷新当前持久性上下文时,所有管理实体状态转换都将转换为关联的数据库语句。 Hibernate的刷新行为并不总是像人们想象的那么明显。
后写
Hibernate尝试将持久性上下文刷新推迟到最后可能的时刻。 传统上,这种策略被称为事务后写 。
后写与Hibernate刷新更相关,而不是任何逻辑或物理事务。 在事务期间,刷新可能会发生多次。
仅对当前数据库事务可见刷新的更改。 在提交当前事务之前, 其他并发事务看不到任何更改。
持久性上下文(也称为第一级缓存 )充当当前实体状态转换和数据库之间的缓冲区。
在缓存理论中 ,后写同步要求对缓存进行所有更改,缓存的责任是最终与后备存储同步。
减少锁争用
每个DML语句都在数据库事务中运行。 基于当前数据库事务隔离级别 ,可以为当前选定/修改的表行获取锁(共享或显式)。
减少锁保持时间可以降低死锁的可能性,并且根据可伸缩性理论 ,它可以提高吞吐量。 锁总是引入串行执行,根据阿姆达尔定律 ,最大加速与当前正在执行的程序的串行部分成反比。
即使在READ_COMMITTED隔离级别,UPDATE和DELETE语句也将获得锁。 此行为可防止其他并发事务读取未提交的更改或修改相关行。
因此,延迟锁定语句(UPDATE / DELETE)可能会提高性能,但是我们必须确保数据一致性不会受到任何影响。
批处理
延迟实体状态转换同步还有另一个主要优点。 由于所有更改都被立即清除,因此Hibernate可能会受益于JDBC批处理优化 。
批处理通过将多个DML语句分组到一个操作中来提高性能,从而减少数据库往返。
读自己写的一致性
由于查询始终针对数据库运行(除非命中了二级查询缓存),因此我们需要确保在查询开始运行之前,所有未决的更改都已同步。
因此,JPA和Hibernate都定义了“ 查询前刷新”同步策略。
从JPA到Hibernate冲洗策略
JPA FlushModeType | 休眠刷新模式 | Hibernate实现细节 |
---|---|---|
汽车 | 汽车 | 有时会在查询执行前刷新会话。 |
承诺 | 承诺 | 会话仅在事务提交之前刷新。 |
总是 | 在执行查询之前, 始终刷新会话。 | |
手册 | 该会话只能 手动刷新 。 | |
决不 | 不推荐使用。 请改用MANUAL。 这是手动刷新的原始名称,但它误导用户以为Session永远不会被刷新。 |
当前冲洗范围
持久性上下文定义了默认的刷新模式,可以在创建Hibernate Session时覆盖它。 查询还可以采用刷新策略,因此会否决当前的持久性上下文刷新模式。
范围 | 冬眠 | JPA |
---|---|---|
持久性上下文 | 届会 | 实体管理器 |
询问 | 询问 标准 | 询问 类型查询 |
敬请关注
在我的下一篇文章中,您将发现Hibernate FlushMode.AUTO破坏了SQL查询的数据一致性,并且您将看到如何克服这一缺点。
翻译自: https://www.javacodegeeks.com/2014/08/a-beginners-guide-to-jpahibernate-flush-strategies.html