Hibernate中一级缓存与二级缓存的区别是什么?
Hibernate 一级缓存与二级缓存核心差异
二者都是Hibernate提供的内存缓存机制,目的是降低数据库访问频次、提升ORM层的操作效率,但核心设计定位完全不同,具体差异如下:
1. 作用域与生命周期
- 一级缓存(又称Session缓存):单Session级别独享,生命周期和所属Session完全绑定,Session初始化时缓存创建,Session关闭时缓存自动销毁。不同Session之间的一级缓存完全隔离,数据互不共享。该缓存默认全局开启,无需额外配置,所有Hibernate的数据库操作都必须经过一级缓存。
- 二级缓存(又称SessionFactory缓存):SessionFactory全局共享,所有由同一个SessionFactory实例创建的Session都可以访问该缓存的数据,生命周期和SessionFactory绑定,只有应用停止或主动销毁SessionFactory时才会清空缓存。该缓存默认关闭,需要手动配置启用,同时要指定第三方缓存实现(如Ehcache、Redis等)。
2. 存储逻辑
- 一级缓存存储的是实体对象的直接引用,同一次会话内多次查询同ID的实体,返回的是内存中同一个对象实例,修改对象属性后,Session flush时会自动同步到数据库。
- 二级缓存存储的是实体的散列化状态数据,而非对象引用,从二级缓存查询到数据后,Hibernate会根据散列数据重新构造新的实体对象返回。
3. 并发特性
- 一级缓存为单Session独有,不存在多线程并发访问冲突,天然线程安全,无需额外配置并发策略。
- 二级缓存为全局共享资源,多Session多线程同时操作同一份缓存数据时会出现并发问题,需要手动配置缓存并发访问策略(可选只读、非严格读写、读写、事务型四种),避免出现脏数据。
4. 适用场景
- 一级缓存适合单次会话内多次查询同一实体的场景,比如同一个业务操作内反复调用同ID的用户数据,第二次及之后的查询直接走内存,无需发SQL到数据库。
- 二级缓存适合全应用范围内高频查询、低修改频率的公共数据,比如系统配置、字典表、公共基础信息等,这类数据全局访问频次高、更新频率极低,用二级缓存可以大幅降低数据库的重复查询压力。
常见误区说明:你提到的「先在JVM中存储数据再同步到数据库」仅针对一级缓存有效,二级缓存默认不会参与数据写入同步,若配置了可写的二级缓存,需要额外配套缓存更新策略,否则会出现缓存与数据库数据不一致的问题。
一级缓存效果示例代码
Session session = sessionFactory.openSession(); // 第一次查询,发送SQL到数据库,结果存入一级缓存 User user1 = session.get(User.class, 1L); // 第二次查询同ID实体,直接读取一级缓存,不发SQL User user2 = session.get(User.class, 1L); // 输出true,二者是同一个对象引用 System.out.println(user1 == user2); session.close(); // 一级缓存随Session销毁 // 新建Session,一级缓存完全隔离 Session newSession = sessionFactory.openSession(); User user3 = newSession.get(User.class, 1L); // 输出false,不同Session的一级缓存不共享 System.out.println(user1 == user3); newSession.close();
内容的提问来源于stack exchange,提问作者Popovych Taras
相关产品推荐
相关产品推荐

