【异常】解决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在执行按规范命名的删除操作时执行流程如下

先查询:其中query对象中的queryString是使用我们定义的参数,构建了一个查询语句
select generatedAlias0 from student as generatedAlias0 where generatedAlias0.name=:param0

再删除:根据查询出数据再构造出根据主键进行删除的语句,最终执行语句如下
delete from sutdent where id=?

删除语句执行完成后会有一个检验verifyOutcome:检验查询个数和删除个数是否一致,不一致代表失败,抛出异常。

例子中,AB两个线程同时对一个数据进行删除,两个线程都会进行查询操作,查询出待删除数据为1,然后A线程将数据删除,并校验通过;B线程删除时,变更行数为0,校验失败则抛出ObjectOptimisticLockingFailureException Batch update returned unexpected row count from update乐观锁异常。


浙公网安备 33010602011771号