【Java】mybatis-plus乐观锁-基本使用
乐观锁(Optimistic Locking)是解决并发问题的重要机制。它通过在数据更新时验证数据版本来确保数据的一致性,从而避免并发冲突。与悲观锁不同,乐观锁并不依赖数据库的锁机制,而是通过检查数据的版本或标志字段来判断数据是否被其他事务修改过。
MyBatis-Plus 提供了便捷的乐观锁支持,通过在实体类中添加版本号字段(通常是一个 int 或 long 类型的字段),并在更新操作时检查版本号,以确保数据的一致性和完整性,同时不影响系统的并发性能。
乐观锁的工作原理
- 版本号字段:在实体类中添加一个版本号字段,通常为version
- 更新操作:在更新操作是,增加一个条件,检查版本号是否匹配。如果不匹配,表示数据已经被其他事务修改,更新操作失败。
执行SQL如下
update t_user balance=?,version=? where id=? and version=?
Mybatis-Plus通过拦截器会自定将乐观锁逻辑加入sql中
使用Mybatis-Plus注意:
乐观锁支持的数据类型只有:int,Integer,long,Long,Date,Timestamp,LocalDateTime
仅支持updateById(id)与update(entity,wrapper)方法
另外,每次操作前都是先查询,替换,再更新,否则乐观锁无效
快速上手
建表
CREATE TABLE `t_user` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(255) DEFAULT NULL COMMENT '名字', `balance` int(11) DEFAULT NULL COMMENT '余额', `version` int(11) NOT NULL DEFAULT '0' COMMENT '乐观锁版本号', `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, `update_time` datetime DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4;
实体类
@Data @TableName("t_user") public class User { @TableId(type = IdType.AUTO) private Integer id; private String name; private Integer balance; @Version private Integer version; private Date createTime; private Date updateTime; }
mapper
@Mapper public interface UserMapper extends BaseMapper { }
service
@Service public class UserService extends ServiceImpl { }
配置
@Configuration public class MybatisPlusConfig { @Bean public MybatisPlusInterceptor mybatisPlusInterceptor(){ // MybatisPlus 拦截器 MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); // 乐观锁插件 interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor()); return interceptor; } }
测试代码
@SpringBootTest public class MpApplicationTests { @Autowired private UserService userService; @Test public void test1(){ User user = userService.getById(1); user.setName("xxx"); user.setBalance(18); boolean b = userService.updateById(user); System.out.println(b); } }
查看执行后的sql
UPDATE t_user SET name=?, balance=?, version=?, create_time=? WHERE id=? AND version=?
失效情况
// 这种情况由于没有先进行查询,乐观锁插件会失效 // 执行sql如下 // UPDATE t_user SET name=?, balance=? WHERE id=? @Test public void test1(){ User user = new User(); user.setId(1) user.setName("xxx"); user.setBalance(18); boolean b = userService.updateById(user); System.out.println(b); }
(图片来源网络,侵删)
(图片来源网络,侵删)
(图片来源网络,侵删)
免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们。