乐观锁是为了解决应用多实例,数据库单一实例时,并发修改同一条记录可能造成的并发问题。一般来说,乐观锁的实现方案都是:
- 首先自己实现查询需要修改记录的当前版本version;
- 后续需要更新该记录时带上刚才的版本号;
- mybatis-plus执行SQL更新时以版本号version为一个匹配条件,并自动把version值增加;
- 只有version为刚才查询出来的值时才证明这期间没有其它服务更改过,才能更改成功;
代码示例很简单:
-
增加Mybatis-Plus的配置,添加乐观锁拦截器;
@Configuration public class MybatisPlusConfig { @Bean public MybatisPlusInterceptor mybatisPlusInterceptor(){ MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor(); mybatisPlusInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor()); return mybatisPlusInterceptor; } }
-
实体类需要增加version字段,建议采用Integer或者Long类型;并且加上@Version注解。
@Data @TableName("zx_course") public class Course { @TableId(type = IdType.ASSIGN_ID) private String courseId; private String courseName; @Version private Long version; }
-
数据库表增加相应的version字段,对应为bigint类型,非空,缺省默认为1;
ALTER TABLE zhangxun.zx_course ADD version BIGINT DEFAULT 1 NOT NULL;
-
编写controller
// 更新操作 @PostMapping("/updateCourse") public Integer updateCourse(@RequestBody Course course){ // 入参course:version=1,模拟更新前查到了version QueryWrapper<Course> queryWrapper = new QueryWrapper<>(); queryWrapper.eq("course_id", course.getCourseId()); // UPDATE zx_course SET course_name=?, version=? WHERE (course_id = ? AND version = ?) return courseMapper.update(course, queryWrapper); }
如果当前version为1,执行后就会发现version被更新为了2。
官网文档强调,当version为整数类型时,自动采用自增+1的操作去更新version。且仅限updateById和update两个方法才有效。
网友评论