从hibernate并发更新报错问题说起

文章讨论了一次生产环境中遇到的并发更新异常,具体表现为OptimisticLockException。问题源于Quarkus框架升级后,其依赖的Hibernate版本降级,导致了一个已修复的bug再次出现,该bug与乐观锁机制有关。解决方案是引入Hibernate的特定修复版本。文章还介绍了JPA、SpringDataJPA的基本概念以及它们如何简化数据库操作,包括基于方法名的查询和自定义查询。此外,详细阐述了Hibernate的flush机制和不同flush模式的影响。

问题描述

最近在生产环境中碰到一个并发更新的错误,具体报错信息为:

javax.persistence.OptimisticLockException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1;

看报错信息判断是并发更新失败引起的,而业务表里刚好有个version字段,通过javax.persistence.Version进行注解,该注解用于数据库乐观锁版本控制。

但问题在于线上虽然发布了新版本,但是并没有对报错的相关代码有任何变更。最后经过一系列验证发现,该报错是由hibernatete包升级引起的。

具体来说,就是项目使用了Quarkus框架,并在本次发布时将其由2.13.3版本升级到了2.15.3版本。相应的,quarkus-spring-data-jpa也做了同样的升级。而quarkus-spring-data-jpa 中引用了hibernate-core的包,且在升级过程中由5.6.15版本降低到了5.6.14版本。

需要注意的是,并不是Quarkus版本越高,依赖的其他三方包的版本就越高。Quarkus的稳定版本是一直在持续维护的,也就是说,有可能低版本的quarkus在维护后比高版本的quarkus使用的三方包的版本要高。

查询官方release note可以看到,hibernate 5.6.15版本修复了一个bug,描述如下:
在这里插入图片描述
这个bug就是说将属性设置为当前的属性时会导致不必要的更新。继续进入HHH-16049报告页可以看到,该bug可能是在解决HHH-15634问题时引入的:
在这里插入图片描述
在github上该bug描述如下:
在这里插入图片描述

在Quarkus中,除了2.14.1-2.16.1引用了hibernate 5.6.14之外,其他的版本都没有影响。

解决办法也很简单,那就是再引入hibernate 5.6.15版本,这样就可以保证系统优先使用Hibernate 5.6.15了,该版本不存在此bug。

JPA和Spring Data JPA

JPA(Java Persistence API)即Java持久化API,是一套基于ORM的思想的规范。换句话说,JPA只有定义没有实现,其内部只有一系列接口和抽象类。

JPA是由具体的db访问框架来实现的,如Hibernate,EclipseLink,OpenJPA等。

那Spring Data JPA又是什么东西呢?

Spri

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值