同一SessionFactory下多Session间共享Hibernate批量操作状态的方法
Hibernate的每个Session都是独立的一级缓存(会话缓存),未提交的批量操作只会保存在当前Session的缓存中,不会同步到数据库或二级缓存——二级缓存仅用于共享已提交的持久化数据,所以新Session完全感知不到其他Session未提交的操作,这是设计上的默认行为。
提交事务(最直接):如果业务允许提交Session1的事务,执行完批量操作后调用:
session.flush(); // 将缓存操作同步到数据库 transaction.commit(); // 提交事务,持久化变更此时变更会写入数据库,二级缓存也会自动更新,新Session查询时就能拿到最新数据。如果需要保持事务原子性,可考虑拆分事务或使用分布式事务。
强制刷新查询(针对未提交场景的妥协):如果不能提交事务,新Session查询时可以强制绕过二级缓存、直接从数据库读取(但如果Session1没执行flush,数据库里还是旧数据):
session.setCacheMode(CacheMode.REFRESH); List<Entity> entities = session.createQuery("from Entity", Entity.class).list();或者对特定实体调用
session.refresh(entity),但批量场景下实用性较低。版本控制避免脏数据冲突:给实体添加
@Version注解实现乐观锁,即使新Session看不到未提交操作,当Session1提交时会检查版本号,若新Session已修改同一数据则抛出异常,避免脏写。这不能让新Session提前看到变更,但能保证数据一致性:@Entity public class Entity { @Id private Long id; @Version private Integer version; // 其他字段 }临时表关联(极端场景):如果必须让新Session感知未提交的批量删除/添加,可将操作记录写入数据库临时表,新Session查询时关联临时表过滤结果。比如批量删除时,先把要删除的ID存入临时表,新Session查询时排除这些ID;但这会脱离Hibernate ORM管理,需要手动维护临时表,复杂度较高。
内容的提问来源于stack exchange,提问作者sunny

