MyBatis-Plus使用乐观锁进行数据更新

使用乐观锁进行数据更新

1、基本介绍

乐观锁的应用场景是当要更新一条记录的时候,希望这条记录没有被别人更新。
注意

目前乐观锁仅支持 updateById(id) 与 update(entity, wrapper) 方法 在 update(entity,
wrapper) 方法下,wrapper 不能复用!!!

乐观锁实现方式如下:

取出记录时,获取当前 version 执行更新时,带上这个 version,即 set version = new Version
where version = old Version 如果 version 不对,就更新失败

MyBatis-Plus 是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。它内置了对乐观锁的支持。乐观锁主要是用来控制并发操作,其核心思想是假设数据在更新过程中不会被其他线程修改,因此它不会像悲观锁那样在数据处理过程中进行加锁,而是通过一个“版本号”或者是“时间戳”进行控制。

为了在 MyBatis-Plus 中使用乐观锁,你需要以下几个步骤:

  1. 添加乐观锁插件
    首先,需要在你的 MyBatis-Plus 配置类中添加乐观锁插件的配置。
import com.baomidou.mybatisplus.extension.plugins.OptimisticLockerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.mybatis.spring.annotation.MapperScan;

@Configuration
@MapperScan("com.example.mapper")
public class MybatisPlusConfig {
    @Bean
    public OptimisticLockerInterceptor optimisticLockerInterceptor() {
        return new OptimisticLockerInterceptor();
    }
}
  1. 在实体类中添加版本号字段
    在你的实体类中添加一个用于控制乐观锁的版本号字段,通常是version,并且在该字段上添加@Version注解。
import com.baomidou.mybatisplus.annotation.Version;

public class User {
    private Long id;
    private String name;
    private String email;
    @Version
    private Integer version;
    
    // 省略其他字段的getter和setter...
    // 注意添加version字段的getter和setter

    public Integer getVersion() {
        return version;
    }

    public void setVersion(Integer version) {
        this.version = version;
    }
}
  1. 执行更新操作
    当执行更新操作时,MyBatis-Plus 会检查实体类中带有@Version注解的字段,基于这个字段来自动构建乐观锁的 SQL 语句。
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.example.entity.User;
import com.example.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;

public class UserService {
    
    @Autowired
    private UserMapper userMapper;

    public void updateUserById(Long userId) {
        User user = userMapper.selectById(userId);
        if (user != null) {
            user.setEmail("newemail@example.com");
            // 当更新时会根据version字段自动执行乐观锁检查
            int result = userMapper.updateById(user);
            if (result == 0) {
                throw new OptimisticLockingFailureException("更新失败,数据可能已被其他用户修改");
            }
        }
    }
}

在这个例子中,当调用updateById方法时,MyBatis-Plus 会在 SQL 更新语句中加入一个条件来检查version字段,确保这个字段的值与数据库中的值一致,然后在更新成功时自动将这个字段的值加一。如果在更新过程中version字段的值已经被其他线程修改,那么这次更新操作将会失败,result将会是0。

使用乐观锁需要注意的是,每次更新操作都需要重新查询数据库以确保version字段的值是最新的,否则可能会导致更新失败。此外,乐观锁并不能完全保证数据的一致性,在高并发的场合下可能仍然会出现问题,比如“ABA”问题,因此在这些场景下可能需要其他的并发控制手段。

查看原文

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值