关于hibernate的缓存的一点思考

编写代码时,在同一事务中更新数据库对象后再次查询,获取不到更新后的数据。先猜测是事务原因,调整事务执行方式未解决。后聚焦hibernate缓存,用flush()、clear()、refresh()方法测试,发现clear()和refresh()可解决,分析得知基于sql更新操作同步缓存会覆盖实体更新。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天在编写代码时发现了一个问题,在同一个事务中,如果提前查询出了某个数据库对象的实体,然后执行了一些更新操作,再次查询该对象时获取不到更新后的数据。
首先我猜测是事务的原因导致的,于是在更新操作中挂起当前事务,另外开启一个transaction去执行,这样就能保证数据库的实体再第二次查询之前一定是最新的。
问题来了,查询的数据仍然不是最新的。。
第二次我把聚焦点放在了hibernate的缓存上,于是我分别尝试了flush()、clear()方法和refresh()。后两种是可以成功解决该问题的。

问题解决了,但是产生问题的原因依然不太理解,在 stackoverflow中有一句话点醒了我
 All flush will do is sending previously cached SQL statements to the database. It will not change your objects that are already in session. In a way it does opposite to what you need. SQL statements from flush may, potentially, override your bulk update changes. 
 翻越我执行的update(我们公司二次封装的)方法的源码,其内部实现依然是基于拼装sql完成的,这样,原因就真相大白了。如同上面所说,基于sql的更新操作如果去同步缓存中的实体会导致我们对实体做的更新操作被覆盖。
 
 
 refresh(object):立即发送一条sql去更新当前实体
 flush():执行缓存中的sql,同步数据库(不会提交事务)
 clear():清空缓存(必须在flush后执行,不然会导致更新失败)
 evict(object):清空缓存中的某一个实体

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值