MyBatis-Plus乐观锁实现教程

精心整理了最新的面试资料和简历模板,有需要的可以自行获取

点击前往百度网盘获取
点击前往夸克网盘获取


MyBatis-Plus乐观锁实现教程

一、什么是乐观锁?

乐观锁是一种并发控制机制,假设多用户并发操作时不会产生冲突,只在数据提交时检测版本一致性。相比悲观锁,乐观锁能有效提高系统吞吐量,适用于读多写少的场景。

二、实现原理

  1. 数据库表中添加version字段(建议使用数值类型)
  2. 更新时检查版本号是否匹配
  3. 版本号匹配则更新成功并自增
  4. 版本号不匹配则抛出OptimisticLockException

三、实现步骤

1. 数据库表添加版本字段

ALTER TABLE user ADD COLUMN version INT DEFAULT 0;

2. 实体类添加@Version注解

@Data
public class User {
    @TableId(type = IdType.AUTO)
    private Long id;
    private String name;
    private Integer age;
    
    @Version
    private Integer version;
}

3. 配置乐观锁插件

@Configuration
public class MybatisPlusConfig {
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        // 添加乐观锁插件
        interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
        return interceptor;
    }
}

4. 更新操作示例

// 先查询获取当前版本号
User user = userMapper.selectById(1L);  // version=1

// 修改数据
user.setName("new name");

// 执行更新(自动处理version)
int result = userMapper.updateById(user);

四、测试用例

@Test
public void testOptimisticLock() {
    // 模拟并发场景
    User user1 = userMapper.selectById(1L);  // version=1
    User user2 = userMapper.selectById(1L);  // version=1

    user1.setAge(20);
    userMapper.updateById(user1);  // version变为2

    user2.setAge(30);
    try {
        userMapper.updateById(user2);  // 此处应抛出异常
    } catch (OptimisticLockException e) {
        System.out.println("乐观锁生效,更新失败");
    }
}

五、注意事项

  1. 版本字段要求

    • 必须使用@Version注解
    • 支持的类型:int/long/Integer/Long/Date
    • 字段值由MyBatis-Plus自动维护
  2. 初始值设置

    • 新增记录时建议设置version=0或1
    • 空值会被认为是初次更新(可能导致逻辑错误)
  3. 更新条件

    • 必须通过updateById或update方法更新
    • 自定义UpdateWrapper需要手动处理版本号
  4. 并发处理建议

    • 捕获OptimisticLockException异常
    • 实现重试机制(最多3次重试示例):
int retry = 0;
while(retry < 3){
    try {
        update(user);
        break;
    } catch (OptimisticLockException e) {
        // 重新查询最新数据
        user = getLatestData();
        retry++;
    }
}

六、最佳实践

  1. 版本字段建议使用包装类型(避免基本类型的默认值问题)
  2. 在数据库设置默认值(推荐DEFAULT 0)
  3. 前端可以返回版本号用于后续更新
  4. 配合逻辑删除时需注意执行顺序(先逻辑删除再版本更新)

七、常见问题

Q:更新时version没有自增?
A:检查是否配置插件、字段是否被@Version注解、是否使用MyBatis-Plus的更新方法

Q:如何自定义版本策略?
A:继承OptimisticLockerInnerInterceptor并重写相关方法

Q:批量更新如何处理?
A:需要使用updateBatchById方法,且每个实体必须包含版本号


通过以上实现,可以有效地防止数据更新时的并发冲突问题。建议在需要高并发写操作的业务场景(如库存扣减、订单状态修改等)中使用乐观锁机制。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

嘵奇

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值