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

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

相关推荐
ะัี潪ิื41 分钟前
springboot加载本地application.yml和加载Consul中的application.yml配置反序列化LocalDate类型差异
spring boot·consul·java-consul
m0_740043732 小时前
SpringBoot05-配置文件-热加载/日志框架slf4j/接口文档工具Swagger/Knife4j
java·spring boot·后端·log4j
招风的黑耳3 小时前
我用SpringBoot撸了一个智慧水务监控平台
java·spring boot·后端
大佐不会说日语~3 小时前
Spring AI Alibaba 的 ChatClient 工具注册与 Function Calling 实践
人工智能·spring boot·python·spring·封装·spring ai
Miss_Chenzr3 小时前
Springboot优卖电商系统s7zmj(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
数据库·spring boot·后端
程序员游老板3 小时前
基于SpringBoot3+vue3的爱心陪诊平台
java·spring boot·毕业设计·软件工程·课程设计·信息与通信
期待のcode3 小时前
Springboot核心构建插件
java·spring boot·后端
Miss_Chenzr3 小时前
Springboot旅游景区管理系统9fu3n(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
数据库·spring boot·旅游
五阿哥永琪4 小时前
Spring Boot 中自定义线程池的正确使用姿势:定义、注入与最佳实践
spring boot·后端·python
canonical_entropy5 小时前
Nop入门:增加DSL模型解析器
spring boot·后端·架构