Spring Data Jpa使用@Version进行数据库乐观锁控制注意事项

在数据库并发操作时,为了保证数据的正确性,我们会做一些并发处理,主要就是加锁。在加锁的选择上,有几种方式,悲观锁,乐观锁。

  • 悲观锁,简单的理解就是把需要的数据全部加锁,在事务提交之前,这些数据全部不可读取和修改。

  • 乐观锁,使用对数据进行版本校验和比较,来对保证本次的更新时最新的,否则就失败。

悲观锁的做法:

select * from user where id=1 for update;
update user set name='abc' where id=1;

这样,id为1的这行记录,就被锁住,在事务提交之前,他不可被其他事务读取和修改。

乐观锁的做法:

select id,name,version from user where id=1;

假设本次查询version=1,在更新操作时,

update user set name='abc', version=version+1 where id=1 and version=1

这样,当其他事务在本次事务提交之前更新了,version就会+1,就不是刚才查询到的1,本次update 就不会被执行。

在JPA中,我们可以使用@Version在某个字段上进行乐观锁控制。
在这里插入图片描述

  • 如对象中有version属性,并使用了@version,在更新数据时请带上version数据和主键,这样可直接利用save方法进行更新,当然这限于全部属性更新,局部更新时请使用@modify@update方法。

  • 当乐观锁更新失败的时候,会抛出异常:org.springframework.orm.ObjectOptimisticLockingFailureException

  • 当使用mysql数据库且JPA主键策略为@GeneratedValue(strategy = GenerationType.IDENTITY),全局更新未带version数据时,更新操作会变为保存操作。

原文地址:https://www.cnblogs.com/gmhappy/p/13457037.html