当前位置: 首页 > news >正文

【Java】mybatis-plus乐观锁-基本使用

乐观锁(Optimistic Locking)是解决并发问题的重要机制。它通过在数据更新时验证数据版本来确保数据的一致性,从而避免并发冲突。与悲观锁不同,乐观锁并不依赖数据库的锁机制,而是通过检查数据的版本或标志字段来判断数据是否被其他事务修改过。
MyBatis-Plus 提供了便捷的乐观锁支持,通过在实体类中添加版本号字段(通常是一个 int 或 long 类型的字段),并在更新操作时检查版本号,以确保数据的一致性和完整性,同时不影响系统的并发性能。

乐观锁的工作原理

  1. 版本号字段:在实体类中添加一个版本号字段,通常为version
  2. 更新操作:在更新操作是,增加一个条件,检查版本号是否匹配。如果不匹配,表示数据已经被其他事务修改,更新操作失败。
    执行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;@Versionprivate Integer version;private Date createTime;private Date updateTime;
}

mapper

@Mapper
public interface UserMapper extends BaseMapper<User> {
}

service

@Service
public class UserService extends ServiceImpl<UserMapper, User> {
}

配置

@Configuration
public class MybatisPlusConfig {@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor(){// MybatisPlus 拦截器MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();// 乐观锁插件interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());return interceptor;}}

测试代码

@SpringBootTest
public class MpApplicationTests {@Autowiredprivate UserService userService;@Testpublic 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=?@Testpublic void test1(){User user = new User();user.setId(1)user.setName("xxx");user.setBalance(18);boolean b = userService.updateById(user);System.out.println(b);}
http://www.xdnf.cn/news/730261.html

相关文章:

  • 高效微调大模型:LoRA技术详解
  • python里的Matplotlib库
  • C#面试问题41-60
  • 嵌入式(1):STM32 GPIO与AFIO深度解析:从原理到高阶应用实战
  • YOLO使用SAHI进行小目标检测
  • 深度剖析Node.js的原理及事件方式
  • AgenticSeek,开源本地通用AI Agent,自主执行任务
  • 从零开始手写一个Promise,彻底理解异步编程的核心原理
  • 如何获取Minio元数据
  • 每日八股文5.30
  • 谷云科技发布业内首份 Oracle OSB 迁移到 iPaaS 技术白皮书
  • 40. 自动化异步测试开发之编写异步业务函数、测试函数和测试类(类写法)
  • Delphi读写Mifare Desfire Ev1 Ev2 EV3卡修改AES密钥源码
  • 39. 自动化异步测试开发之编写异步业务函数、测试函数和测试类(函数写法)
  • 逆向分析基础总结
  • HTML 文件反编译指南:优化与学习网页代码
  • 【容器docker】启动容器kibana报错:“message“:“Error: Cannot find module ‘./logs‘
  • STUSB4500 PPS(PD3.0)快充SINK模块——应用 解析
  • [学习] C语言的回调函数(代码示例)
  • 数据基座觉醒!大数据+AI如何重构企业智能决策金字塔(下)
  • 【Linux 学习计划】-- 命令行参数 | 环境变量
  • 【目标检测】【AAAI-2022】Anchor DETR
  • 【Golang进阶】第八章:并发编程基础——从Goroutine调度到Channel通信实战
  • Redis持久化机制
  • MPC5744P——eTimer简介
  • Github 2025-05-30Java开源项目日报Top10
  • 《深入解析Go语言结构:简洁高效的工程化设计》
  • 基于 KubeKey 3.1.9,快速部署 K8s 1.33.0 高可用集群
  • Java复习Day23
  • haproxy 搭建web群集