You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Hibernate持久态对象事务提交后修改未同步数据库但查询返回新值原因

你的猜测完全正确,问题本质是Hibernate的两个核心特性的共同作用:脏数据同步的触发时机、Session一级缓存的特性。

核心原因说明

  • 首先,持久态对象自动同步到数据库的脏检查机制,仅会在活动事务的提交阶段触发。事务提交完成后,即使Session还未关闭,你对持久态对象做的修改,如果没有后续的事务提交、或者主动调用flush()等同步操作,永远不会被写入数据库。
  • 其次,你最后打印出role111确实是一级缓存导致的:Session的一级缓存生命周期和Session保持一致,事务提交不会清空一级缓存。你修改role的name为role111后调用session.get(Role.class, 1),会直接命中一级缓存中存储的已修改的对象,不会发起数据库查询,所以拿到的是修改后的role111,这个修改只存在于JVM内存的缓存中,和数据库没有同步。

对应你的代码执行流程逐段验证

  1. 开启事务后调用session.save(role),role对象转为持久态,被纳入Session的一级缓存管理。
  2. 修改name为role11,此时脏检查标记该属性已变更,事务执行commit()时,Hibernate会自动把所有未同步的脏修改刷入数据库,此时数据库对应行的name字段被更新为role11。
  3. 事务提交完成后,你修改name为role111,此时没有活动的事务,也没有主动调用同步到数据库的操作,这个修改仅停留在一级缓存的对象中。
  4. 调用session.get()时直接返回缓存中的对象,所以打印role111,直到Session被关闭,这个修改都没有被同步到数据库,因此最终数据库存储的是role11。

解决方案

如果需要将role111也写入数据库,可选方案:

  • 把role.setName("role111")的逻辑移到事务commit()之前执行。
  • 事务提交后重新开启一个新事务,显式调用session.update(role)或者session.merge(role)后再提交新事务。

内容的提问来源于stack exchange,提问作者Denys_newbie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.23 14:15:02