题目
Hibernate一级缓存与二级缓存的区别及二级缓存配置实践
信息
- 类型:问答
- 难度:⭐⭐
考点
缓存机制理解,性能优化,配置管理,并发策略
快速回答
Hibernate缓存分为两级:
- 一级缓存(Session缓存):默认开启,生命周期与Session绑定,提供事务级别的缓存
- 二级缓存(SessionFactory缓存):需显式配置,跨Session共享,提供应用级别的缓存
关键区别:
- 作用域:一级缓存属于Session级别,二级缓存属于SessionFactory级别
- 并发策略:二级缓存需配置并发访问策略(如read-write)
- 失效场景:一级缓存随Session关闭失效,二级缓存需手动管理失效
一、缓存机制原理
一级缓存:Hibernate内置的Session级别缓存,自动启用。当Session执行查询时:
1. 优先查询一级缓存
2. 不存在则查数据库并缓存结果
3. 同一事务中重复查询相同数据直接返回缓存对象
二级缓存:进程或集群范围缓存,需第三方缓存库实现(如Ehcache)。工作流程:
1. Session查询时先查一级缓存
2. 一级缓存未命中则查二级缓存
3. 二级缓存未命中才查数据库
4. 结果同时存入一、二级缓存
二、代码配置示例
启用二级缓存(hibernate.cfg.xml):
<!-- 启用二级缓存 -->
<property name="hibernate.cache.use_second_level_cache">true</property>
<!-- 指定缓存提供商 -->
<property name="hibernate.cache.region.factory_class">
org.hibernate.cache.ehcache.EhCacheRegionFactory
</property>
<!-- 启用查询缓存 -->
<property name="hibernate.cache.use_query_cache">true</property>实体类注解配置(Ehcache):
@Entity
@Cacheable
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE) // 读写并发策略
public class Product {
@Id
private Long id;
private String name;
// 其他字段及方法
}三、最佳实践
- 适用场景:
- 一级缓存:事务内重复访问相同实体
- 二级缓存:频繁读取的静态数据(如国家列表、配置信息)
- 避坑指南:
- 避免缓存频繁更新的数据(导致缓存命中率低)
- 集群环境使用分布式缓存(如Redis)
- 对查询缓存调用
setCacheable(true)
- 监控手段:通过
Statistics API获取缓存命中率
四、常见错误
- N+1查询问题:未正确配置关联对象缓存导致多次查询
- 解决方案:在集合映射添加
@Cache(usage=...)
- 解决方案:在集合映射添加
- 脏读:使用
READ_WRITE策略时未配置事务管理 - 内存溢出:未限制缓存大小时缓存过多数据
五、扩展知识
- 查询缓存:缓存查询语句结果集,需配合二级缓存使用
- 缓存策略对比:
策略 适用场景 锁机制 READ_ONLY 永不修改的数据 无锁 READ_WRITE 经常读偶尔写 软锁 NONSTRICT_READ_WRITE 数据更新后允许短暂不一致 无锁 - 缓存失效:通过
sessionFactory.getCache().evictEntity(Product.class, productId)手动清除