公众号merlinsea
乐观锁介绍:
乐观锁就是不通过物理加锁的方式以保证共享变量线程安全的一种设计思路。 具体设计思路如下:CAS【compare and swap】,首先在数据库表设计时增
version字段,后续每次修改成功以后version字段都要自增。线程A首先读取到了某条记录【该条记录包含其version字段的值】,线程A修改了该条记录以后,将新的记录重新写会数据库的 时候,会比较数据库中这条记录的version还是不是自己之前读到的那个version,如果是的话说明线程A操作的中途没有其他 线程修改过该条记录,因此可以放心写回;如果不是的话说明线程A操作的中途有其他线程修改过了这条记录,因此线程A放弃本次 更新操作。
1、model实体类中增加@Version注解
@Data @TableName("banner") public class BannerDO { @TableId(value = "id",type = IdType.AUTO) private Integer id; private String img; private String url; private Integer weight; /** * @Version 是mybatis plus用于表示乐观锁机制的注解 */ @Version private Integer version; }
2、增加乐观锁插件配置,并交由spring ioc管理
@Configuration public class MybatisPlusConfig { @Bean public MybatisPlusInterceptor mybatisPlusInterceptor(){ MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); //分页插件 interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); //乐观锁插件 interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor()); return interceptor; } }
3、乐观锁更新测试
通过测试的结果可以发现,mybatis plus整合乐观锁底层其实就是会自动在where条件中拼接上【version=原version】的条件,以确保更新的时候的原子操作。
/** * 乐观锁测试 * 因为开启了乐观锁配置,因此在更新的时候会自动拼接版本号字段 */ @Test public void testOptimi(){ //先根据ID找记录,得到id 和 version BannerDO bannerDO = bannerMapper.selectOne(new QueryWrapper<BannerDO>().eq("id",3)); //修改记录 bannerDO.setUrl("upadte optimite"); //以乐观锁的方式重新插入 bannerMapper.updateById(bannerDO); }