Mybatis-Plus中的乐观锁与悲观锁

乐观锁

乐观锁(Optimistic Lock): 乐观锁是一种通过版本号(Version)或时间戳(Timestamp)来实现的并发控制机制。在更新数据时,会先检查数据版本号或时间戳是否匹配,如果匹配则更新数据并将版本号加一(或更新时间戳),否则认为是数据已经被其他事务修改过,不进行更新操作

乐观锁在Springboot中的实现

1.在数据库表中添加字段version

2.添加乐观锁配置

java 复制代码
        // 配置乐观锁
        interceptor.addInnerInterceptor((new OptimisticLockerInnerInterceptor()));
        return  interceptor;

3.使用注解

java 复制代码
public class Product {

    private Long id;
    private String name;
    private Integer price;
    @Version
    private Integer version;

}

完整代码:

java 复制代码
//实体
package com.qing.mybatislearning.pojo;

import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.Version;
import lombok.Data;
import org.springframework.stereotype.Repository;

@Data
@TableName("t_product")
public class Product {

    private Long id;
    private String name;
    private Integer price;
    @Version
    private Integer version;

}

//配置类
package com.qing.mybatislearning.config;


import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
//扫描Mapper接口所在的包
@MapperScan("com.qing.mybatislearning.mapper")
public class MyBatisPlusConfig {
    //  Ctrl + p:查看方法的参数
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor(){
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        //分页配置
        // 设置数据库类型为MYSQL,原因是不同数据库的分页方法不同
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        // 配置乐观锁
        interceptor.addInnerInterceptor((new OptimisticLockerInnerInterceptor()));
        return  interceptor;
    }


}



// 接口
package com.qing.mybatislearning.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.qing.mybatislearning.pojo.Product;
import org.springframework.stereotype.Repository;

@Repository
public interface ProductMapper extends BaseMapper<Product> {

}


//测试类
package com.qing.mybatislearning;

import com.qing.mybatislearning.mapper.ProductMapper;
import com.qing.mybatislearning.pojo.Product;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
public class MybatisPlusLeGuanSuoTest {

    @Autowired
    private ProductMapper productMapper;

    @Test
    public void Test1(){
        //小李查询商品价格
        Product productLi = productMapper.selectById(1);
        System.out.println("小李获取的产品信息是: " + productLi.getPrice());

        //小王查询商品价格
        Product productWang = productMapper.selectById(1);
        System.out.println("小王获取的产品信息是: " + productWang.getPrice());
        //小李将价格+50
        productLi.setPrice(productLi.getPrice() + 50);
        productMapper.updateById(productLi);
        //小王将价格-30
        productWang.setPrice(productWang.getPrice() - 30);
        int result = productMapper.updateById(productWang);
        if(result == 0){
            Product productWangNew = productMapper.selectById(1);
            productWangNew.setPrice(productWangNew.getPrice() - 30);
            productMapper.updateById(productWangNew);
        }

        //老板查询商品价格
        Product productBoss = productMapper.selectById(1);
        System.out.println("老板获取的产品信息是: " + productBoss.getPrice());
    }
}

悲观锁

悲观锁(Pessimistic Lock): 悲观锁是一种在操作数据之前先加锁的机制,以避免数据被其他事务修改。在 MyBatis-Plus 中,可以通过 selectForUpdate 方法来实现悲观锁的功能,例如:

java 复制代码
User user = userMapper.selectById(userId, new QueryWrapper<User>().forUpdate());

上面的代码会在查询用户数据时加上 for update,使得查询结果被加上排它锁。

总的来说,乐观锁适合并发量不高的场景,通过版本号或时间戳来控制数据的更新;而悲观锁适合并发量高、需要确保数据一致性的场景,通过数据库锁来保证数据的完整性。在实际应用中,可以根据业务需求和系统的并发情况选择合适的锁机制。

相关推荐
xuxie1342 分钟前
SpringBoot文件下载(多文件以zip形式,单文件格式不变)
java·spring boot·后端
LiRuiJie2 小时前
深入剖析Spring Boot / Spring 应用中可自定义的扩展点
java·spring boot·spring
尚学教辅学习资料4 小时前
Ruoyi-vue-plus-5.x第五篇Spring框架核心技术:5.1 Spring Boot自动配置
vue.js·spring boot·spring
晚安里4 小时前
Spring 框架(IoC、AOP、Spring Boot) 的必会知识点汇总
java·spring boot·spring
上官浩仁5 小时前
springboot ioc 控制反转入门与实战
java·spring boot·spring
叫我阿柒啊6 小时前
从Java全栈到前端框架:一位程序员的实战之路
java·spring boot·微服务·消息队列·vue3·前端开发·后端开发
中国胖子风清扬6 小时前
Rust 序列化技术全解析:从基础到实战
开发语言·c++·spring boot·vscode·后端·中间件·rust
JosieBook10 小时前
【SpringBoot】21-Spring Boot中Web页面抽取公共页面的完整实践
前端·spring boot·python
刘一说10 小时前
Spring Boot+Nacos+MySQL微服务问题排查指南
spring boot·mysql·微服务
javadaydayup11 小时前
为什么 MyBatis Mapper 接口能像普通 Bean 一样被 @Autowired?
后端·mybatis