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,使得查询结果被加上排它锁。

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

相关推荐
云创智城-yuncitys9 小时前
YunParking 4.0:JDK 17 与 Spring Boot 3.2 的停车云升级
java·开发语言·spring boot
wljt10 小时前
公司二-面试题
java·开发语言·mybatis
paopaokaka_luck11 小时前
灾害应急物资管理系统(AI应急助手、Echarts可视化数据看板、捐赠入库联动、 物资全流程管理、库存变动追溯、灾情资讯与互动反馈、物资发放公示)
java·前端·javascript·spring boot·mysql·tomcat·echarts
学长毕设13 小时前
基于SpringBoot的网上流浪狗救助捐赠平台-附源码
java·spring boot·后端
VimorphTech13 小时前
文本已经改了,旧的音频生成结果还能回写吗?
java·数据库·mybatis
码农的日常13 小时前
前后端Long精度丢失的踩坑
spring boot·架构
杨运交14 小时前
086-对象存储模块-基于Spring Boot的文件存储模块监控设计与实现
java·spring boot·后端
wifi___16 小时前
SpringBoot自动装配原理
java·spring boot·后端
Small-Young16 小时前
数据库乐观锁深度解析:MySQL、PostgreSQL 实战 + Spring Boot 集成指南
数据库·spring boot·mysql·postgresql·乐观锁·并发控制
她的男孩17 小时前
租户 A 的验证码,却用了租户 B 的 AccessKey:Forge Admin 修跨租户短信串发
java·spring boot·saas