主要适用场景:当要更新一条记录的时候,希望这条记录没有被别人更新,也就是说实现线程安全的数据更新
乐观锁实现方式:
取出记录时,获取当前version
更新时,带上这个version
执行更新时, set version = newVersion where version = oldVersion
如果version不对,就更新失败
首先,向数据库表中添加version字段
然后在实体类中添加version属性
@Data@Componentpublic class User { private Long id; private String name; private Integer age; private String email; @TableField(fill = FieldFill.INSERT) private Date createTime; @TableField(fill = FieldFill.INSERT_UPDATE) private Date updateTime; @Version //乐观锁version @TableField(fill = FieldFill.INSERT) private Integer version;}
同时我们在version属性上添加@TableField(fill = FieldFill.INSERT)注解,让其第一次插入时自动填充一个1(如何实现自动填充->自动填充)
然后我们创建一个配置类如下:
@Configuration@MapperScan(value = ("com.kk.mpdemo.mapper"))public class MpConfig { @Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor()); return interceptor; }}
让我们来测试一下吧~
@Test @DisplayName("测试乐观锁") void testOptimisticLocker() { user.setAge(66); user.setEmail("6666@qq.com"); user.setName("马大姐测试乐观锁"); userMapper.insert(user); }
可以看到,version字段有了数值1
@Test @DisplayName("更新乐观锁") void testUpdateOptimisticLocker(){ //先查询再更新 User user = userMapper.selectById(1492433687321886722L); user.setAge(99); user.setName("玛玛哈哈更新乐观锁"); userMapper.updateById(user); }
可以看到,此时version变成了2,若是我们查询出oldVersion并准备更新时另有他人抢先我们一步更新了该条数据,那么我们此次更新操作携带version将会与数据库中此时存储的version对比不上从而导致更新失败。
具体的sql语句如下
UPDATE user SET name=?, age=?, email=?, create_time=?, update_time=?, version=? WHERe id=? AND version=?