首页 > 编程语言 >Java开发学习(四十九)----MyBatisPlus更新语句之乐观锁

Java开发学习(四十九)----MyBatisPlus更新语句之乐观锁

时间:2022-12-29 22:13:23浏览次数:66  
标签:MyBatisPlus private ---- version 线程 user Java 更新 userDao

1、概念

在讲解乐观锁之前,我们还是先来分析下问题:

业务并发现象带来的问题:秒杀

  • 假如有100个商品或者票在出售,为了能保证每个商品或者票只能被一个人购买,如何保证不会出现超买或者重复卖

  • 对于这一类问题,其实有很多的解决方案可以使用

  • 第一个最先想到的就是锁,锁在一台服务器中是可以解决的,但是如果在多台服务器下锁就没有办法控制,比如12306有两台服务器在进行卖票,在两台服务器上都添加锁的话,那也有可能会导致在同一时刻有两个线程在进行卖票,还是会出现并发问题

  • 我们接下来介绍的这种方式是针对于小型企业的解决方案,因为数据库本身的性能就是个瓶颈,如果对其并发量超过2000以上的就需要考虑其他的解决方案了。

简单来说,乐观锁主要解决的问题是当要更新一条记录的时候,希望这条记录没有被别人更新。

2、实现思路

乐观锁的实现方式:

  • 数据库表中添加version列,比如默认值给1

  • 第一个线程要修改数据之前,取出记录时,获取当前数据库中的version=1

  • 第二个线程要修改数据之前,取出记录时,获取当前数据库中的version=1

  • 第一个线程执行更新时,set version = newVersion where version = oldVersion

    • newVersion = version+1 [2]

    • oldVersion = version [1]

  • 第二个线程执行更新时,set version = newVersion where version = oldVersion

    • newVersion = version+1 [2]

    • oldVersion = version [1]

  • 假如这两个线程都来更新数据,第一个和第二个线程都可能先执行

    • 假如第一个线程先执行更新,会把version改为2,

    • 第二个线程再更新的时候,set version = 2 where version = 1,此时数据库表的数据version已经为2,所以第二个线程会修改失败

    • 假如第二个线程先执行更新,会把version改为2,

    • 第一个线程再更新的时候,set version = 2 where version = 1,此时数据库表的数据version已经为2,所以第一个线程会修改失败

    • 不管谁先执行都会确保只能有一个线程更新数据,这就是MybatisPlus提供的乐观锁的实现原理分析。

上面所说的步骤具体该如何实现呢?

3、实现步骤

分析完步骤后,具体的实现步骤如下:

步骤1:数据库表添加列

列名可以任意,比如使用version,给列设置默认值为1

步骤2:在模型类中添加对应的属性

根据添加的字段列名,在模型类中添加对应的属性值

@Data
//@TableName("tbl_user") 可以不写是因为配置了全局配置
public class User {
    @TableId(type = IdType.ASSIGN_UUID)
    private String id;
    private String name;
    @TableField(value="pwd",select=false)
    private String password;
    private Integer age;
    private String tel;
    @TableField(exist=false)
    private Integer online;
    private Integer deleted;
    @Version
    private Integer version;
}
步骤3:添加乐观锁的拦截器
@Configuration
public class MpConfig {
    @Bean
    public MybatisPlusInterceptor mpInterceptor() {
        //1.定义MybatisPlus拦截器
        MybatisPlusInterceptor mpInterceptor = new MybatisPlusInterceptor();
        //2.添加乐观锁拦截器
        mpInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
        return mpInterceptor;
    }
}
步骤4:执行更新操作

添加version数据

@SpringBootTest
class Mybatisplus03DqlApplicationTests {
​
    @Autowired
    private UserDao userDao;
    
    @Test
    void testUpdate(){
        User user = new User();
        user.setId(3L);
        user.setName("Jock666");
        user.setVersion(1);
        userDao.updateById(user);
    }
}

你会发现,我们传递的是1,MybatisPlus会将1进行加1,然后,更新回到数据库表中。

所以要想实现乐观锁,首先第一步应该是拿到表中的version,然后拿version当条件在将version加1更新回到数据库表中,所以我们在查询的时候,需要对其进行查询

@SpringBootTest
class Mybatisplus03DqlApplicationTests {
​
    @Autowired
    private UserDao userDao;
    
    @Test
    void testUpdate(){
        //1.先通过要修改的数据id将当前数据查询出来
        User user = userDao.selectById(3L);
        //2.将要修改的属性逐一设置进去
        user.setName("Jock888");
        userDao.updateById(user);
    }
}

大概分析完乐观锁的实现步骤以后,我们来模拟一种加锁的情况,看看能不能实现多个人修改同一个数据的时候,只能有一个人修改成功。

@SpringBootTest
class Mybatisplus03DqlApplicationTests {
​
    @Autowired
    private UserDao userDao;
    
    @Test
    void testUpdate(){
       //1.先通过要修改的数据id将当前数据查询出来
        User user = userDao.selectById(3L);     //version=3
        User user2 = userDao.selectById(3L);    //version=3
        user2.setName("Jock aaa");
        userDao.updateById(user2);              //version=>4
        user.setName("Jock bbb");
        userDao.updateById(user);               //verion=3?条件还成立吗?
    }
}

运行程序,分析结果:

乐观锁就已经实现完成了,如果对于上面的这些步骤记不住咋办呢?

参考官方文档来实现:https://baomidou.com/pages/0d93c0/#optimisticlockerinnerinterceptor

 

 

标签:MyBatisPlus,private,----,version,线程,user,Java,更新,userDao
From: https://www.cnblogs.com/xiaoyh/p/16468212.html

相关文章

  • 10 个你需要熟悉的 CSS3 属性
    CSS属性被分为不同的类型,如字体属性、文本属性、边框属性、边距属性、布局属性、定位属性、打印属性等。对于初学者来说,需要熟悉并掌握这些属性。前面我们已经了解了30......
  • 三元运算符
    三元运算符packageoperator;publicclassDemo07{publicstaticvoidmain(String[]args){inta=10;intb=20;a+=b;//a=a+b......
  • 算法刷题 Day 2 | 977.有序数组的平方 & 209.长度最小的子数组 & 59.螺旋矩阵II
    977.有序数组的平方题目建议:本题关键在于理解双指针思想题目链接:https://leetcode.cn/problems/squares-of-a-sorted-array/Tips:这道题没有空间复杂度要求,最开始以......
  • CxfWS
    @WebService比较@WebServiceserviceName:指定暴露的服务名,WSDL中由类名+Service,变为指定名(实现类上指定)name:暴露的porttype(接口上指定)与endpointInterfac......
  • 【流水线跳转指令】转移指令及延迟槽最详细讲解
    https://blog.csdn.net/weixin_46318370/article/details/108033218文章转自于可以配合视频一起看->《计算机组成》视频转移指令由于其自身的特殊性,总是会给我们带来一些......
  • 反射
    2、反射机制(比较简单,因为只要会查帮助文档,就可以了。)2.1、反射机制有什么用?通过java语言中的反射机制可以操作字节码文件。优点类似于黑客。(可以读和修改字节码文件。)......
  • 20221229_每日学习记录
    20221229使用下面的命令可以对Linux的结果进行排序ll-h|awk'{print\$5}'|sort|uniq-cpython的pandas读取csv和筛选某一列中数据也在list中importpandas......
  • OpenHarmony应用开发[1]-入门
    目标系统环境系统:HarmonyOS3.0.0(API8)架构:ARM64核心:Cortex-A76核,Cortex-A55核开发环境DevEcoStudio3.0ReleaseArkUI和eTS开发范式OpenHarmony为应用开......
  • 代码随想录算法训练营第二天 | 977 有序数组的平方;209 长度最小的子数组;59 螺旋矩阵
    977有序数组的平方class Solution {public:    vector<int> sortedSquares(vector<int>& nums) {        vector<int> result(nums.size(),0); ......
  • ASP.NET期末大作业————图片管理系统
    项目描述:本课题研究的主要内容是用户的注册与登陆,用户的授权及用户登录后的图片管理界面,包括:图片上传;图片审核;图片入库;图片检索;图片浏览及下载等。开发语言: Asp.net技术......