先来看看官网的解释:
乐观锁的配置需要两步:
1、配置插件
package com.shang.config;
import com.baomidou.mybatisplus.extension.plugins.OptimisticLockerInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;
@MapperScan("com.shang.mapper")
@EnableTransactionManagement //事务管理
@Configuration
public class MybatisPlusConfig {
@Bean
public OptimisticLockerInterceptor optimisticLockerInterceptor() {
return new OptimisticLockerInterceptor();
}
}
2、在实体类字段上添加注解
package com.shang.pojo;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.Version;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
@TableId(type = IdType.AUTO) //设置id自增(雪花算法)
private Long id;
private String name;
private Integer age;
private String email;
@Version //乐观锁version注解
private Integer version;
}
3、测试一下
先用单线程看一下乐观锁能不能成功修改:
@Test
public void testOptimisticLocker(){
//1 查询用户
User user = userMapper.selectById(1L);
//2 修改用户
user.setName("hahaha");
user.setEmail("1600506991@qq.com");
userMapper.updateById(user);
}
测试乐观锁成功的运行结果:
可以看到,能够成功修改。
再用一个线程去插队,看看乐观锁失败的效果:
@Test
public void testOptimisticLocker2(){
//线程1
User user = userMapper.selectById(1L);
user.setName("hahaha111");
user.setEmail("1600506991@qq.com");
//模拟另一个线程插队
User user2 = userMapper.selectById(1L);
user2.setName("hahaha222");
user2.setEmail("1600506991@qq.com");
userMapper.updateById(user2); //插队,抢先更新
//自旋锁来多次尝试提交
userMapper.updateById(user); //如果没有乐观锁,就会覆盖插队线程的值
}
测试一下乐观锁失败的运行结果:
可以看到,在线程2插队以后,原来的user并没有再将插队线程的值覆盖,这就是乐观锁的作用。



