【异常】解决JAP中 Batch update returned unexpected row count from update问题

使用JAP进行数据库操作时,出现ObjectOptimisticLockingFailureException “Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1; statement executed: delete from table_name where id=?”异常。

出现场景

多线程对同一范围数据进行删除/更新操作,有概率会抛出该异常。

解决方式

利用@Query注解定义原生SQL

@Transactional
@Modifying
@Query(value = "delete from student where name=:name",nativeQuery = true)
int deleteByName(@Param("name") String name);

出现原因

JPA对于按照规范命名的删除操作,是先进行查询,得到要删除的数据,然后根据数据生成删除语句,所以报错的语句看起来跟我们写的删除语句不一样。
例如:自定义的是根据名称进行数据删除

@Transactional
int deleteByName(String name);

期望是执行

delete from student where name=?

但是最终报错却是一个根据id进行删除的语句

Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1; statement executed: delete from student where id=?

JAP在执行按规范命名的删除操作时执行流程如下
image
先查询:其中query对象中的queryString是使用我们定义的参数,构建了一个查询语句

select generatedAlias0 from student as generatedAlias0 where generatedAlias0.name=:param0

image
再删除:根据查询出数据再构造出根据主键进行删除的语句,最终执行语句如下

delete from sutdent where id=?

image
删除语句执行完成后会有一个检验verifyOutcome:检验查询个数和删除个数是否一致,不一致代表失败,抛出异常。
image
例子中,AB两个线程同时对一个数据进行删除,两个线程都会进行查询操作,查询出待删除数据为1,然后A线程将数据删除,并校验通过;B线程删除时,变更行数为0,校验失败则抛出ObjectOptimisticLockingFailureException Batch update returned unexpected row count from update乐观锁异常。
image

posted @ 2023-12-03 11:48  此木|西贝  阅读(3211)  评论(0)    收藏  举报