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

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

相关推荐
学长毕设3 小时前
基于SpringBoot的景点管理系统-附源码
java·spring boot·后端
知守观4 小时前
一个方法两个触发口:反编译 XXL-Job 后,我看清了 inner/job 子包的裸奔现状
java·spring boot·微服务
瑞雪兆丰年兮4 小时前
JavaWeb-day14-SpringBootWeb原理篇
java·开发语言·spring boot·spring·bean·mybatis·javaweb
杨凯凡8 小时前
Spring Boot 大文件下载如何实现断点续传?HTTP Range、206 与 416 实战
spring boot·后端·http
nice_lcj52018 小时前
【从零理解 Spring AI · 14】RAG 的四个环节:加载、切分、向量化、检索
java·spring boot·embedding·向量数据库·rag·spring ai·ai应用开发
学长毕设20 小时前
基于springboot科创竞赛信息平台-附源码
java·spring boot·后端
学长毕设21 小时前
基于SpringBoot公务员考试交流平台-附源码
java·spring boot·后端
AI开源软件1 天前
SpringBoot3+AI Agent 智能报销:怎样把对话接进现有财务审批系统
spring boot·ai agent·人工确认·ruoyi office·agentos·智能报销·财务审批
学长毕设1 天前
基于SpringBoot的高校后勤报修管理系统-附源码
java·spring boot·后端