在 Hibernate 中,缓存是提高性能的关键机制,但如果不当使用,可能会造成缓存污染(如脏数据、过时数据等),影响系统的正确性和一致性。要清理缓存、避免缓存污染,需从一级缓存、二级缓存、查询缓存三方面入手。
一级缓存(Session 缓存)
Hibernate 默认开启一级缓存,绑定在 Session
生命周期内。
清理方式:
session.clear()
:清空 Session 中的所有持久化对象。session.evict(Object entity)
:清除某个对象的缓存。session.close()
:关闭 Session 会自动清空一级缓存。
避免污染建议:
- 使用完
Session
后及时关闭,避免数据长时间滞留。 - 对于大批量处理操作,定期调用
session.flush()
+session.clear()
,避免内存占用过高。
二级缓存(SessionFactory 缓存)
可配置使用,如 EhCache、Redis 等,缓存跨 Session 的实体对象。
清理方式:
- 程序手动清除:
SessionFactory sf = ...; sf.getCache().evictEntityData(MyEntity.class); // 清除某个实体的全部缓存 sf.getCache().evictEntityData(MyEntity.class, id); // 清除某个实体的某个实例缓存 sf.getCache().evictAllRegions(); // 清除所有缓存区域
- 缓存策略配置:使用合理的失效策略、过期时间(TTL)、一致性模式(如
READ_WRITE
)。
避免污染建议:
- 开启
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
避免脏数据问题。 - 不要缓存频繁更新或不适合缓存的实体类。
- 对更新数据后,及时让缓存失效或更新缓存。
查询缓存(Query Cache)
缓存查询语句结果,需额外开启。
清理方式:
sessionFactory.getCache().evictQueryRegion(String regionName)
sessionFactory.getCache().evictQueryRegions()
避免污染建议:
- 查询参数必须正确设置,使缓存命中更准确。
- 更新数据后,关联查询缓存也要及时失效。
总结建议
类型 | 清理方法 | 避免污染建议 |
---|---|---|
一级缓存 | session.clear() / evict() | 用完及时关闭 Session,批处理注意定期清理缓存 |
二级缓存 | evictEntityData() | 设置合理策略,及时清除失效数据 |
查询缓存 | evictQueryRegion() | 查询参数明确,数据更新后清除相关缓存 |
如你使用的是 Spring + Hibernate,可以利用事务和缓存机制更细粒度地控制缓存行为,比如使用 @Transactional
配合手动清除缓存区域。