文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

MybatisPlus中@Version注解如何使用

2023-07-02 10:33

关注

这篇文章主要讲解了“MybatisPlus中@Version注解如何使用”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“MybatisPlus中@Version注解如何使用”吧!

注解说明

在 MyBatis Plus 中,使用 @Version 实现乐观锁,该注解用于字段上面

什么是乐观锁

1 乐观锁简介

2 乐观锁实例

存在两个线程 A 和 B,分别从数据库读取数据。执行后,线程 A 和 线程 B 的 version 均等于 1。如下图

MybatisPlus中@Version注解如何使用

线程 A 处理完业务,提交数据。此时,数据库中该记录的 version 为 2。如下图:

MybatisPlus中@Version注解如何使用

线程 B 也处理完业务了,提交数据。此时,数据库中的 version 已经等于 2,而线程的 version 还是 1。程序给出错误信息,不允许线程 B 操作数据。如下图:

MybatisPlus中@Version注解如何使用

实例代码

本实例将在前面用到的 user 表上面进行。在进行之前,现在 user 表中添加 version 字段

ALTER TABLE `user`ADD COLUMN `version`  int UNSIGNED NULL COMMENT '版本信息';

:::info

定义 user 表的 JavaBean,代码如下:

import com.baomidou.mybatisplus.annotation.*; @TableName(value = "user")public class AnnotationUser5Bean {   @TableId(value = "user_id", type = IdType.AUTO)   private String userId;       @TableField("name")   private String name;       @TableField("sex")   private String sex;       @TableField("age")   private Integer age;       @Version   private int version;   // 忽略 getter 和 setter 方法}

添加 MyBatis Plus 的乐观锁插件,该插件会自动帮我们将 version 加一操作

注意,这里和分页操作一样,需要进行配置,如果不配置,@Version是不会生效的

import com.baomidou.mybatisplus.annotation.DbType;import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration; @Configurationpublic class MybatisPlusConfig {     @Bean    public MybatisPlusInterceptor paginationInterceptor() {        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();        // 乐观锁插件        interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());        return interceptor;    } }

测试乐观锁代码,我们创建两个线程 A 和 B 分别去修改用户ID为 1 的用户年龄,然后观察年龄和version字段的值

package com.hxstrive.mybatis_plus.simple_mapper.annotation; import com.hxstrive.mybatis_plus.mapper.AnnotationUser5Mapper;import com.hxstrive.mybatis_plus.model.AnnotationUser5Bean;import org.junit.jupiter.api.Test;import org.junit.runner.RunWith;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.test.context.SpringBootTest;import org.springframework.test.context.junit4.SpringRunner;import java.util.concurrent.CountDownLatch; @RunWith(SpringRunner.class)@SpringBootTestclass AnnotationDemo5 {     @Autowired    private AnnotationUser5Mapper userMapper;     @Test    void contextLoads() throws Exception {        // 重置数据        AnnotationUser5Bean user5Bean = new AnnotationUser5Bean();        user5Bean.setUserId(1);        user5Bean.setAge(0);        user5Bean.setVersion(0);        userMapper.updateById(user5Bean);         // 修改数据        for (int i = 0; i < 10; i++) {            System.out.println("第 " + (i + 1) + " 次修改数据");            final CountDownLatch countDownLatch = new CountDownLatch(2);            modifyUser(countDownLatch, "My-Thread-A", 1);            modifyUser(countDownLatch, "My-Thread-B", 1);            countDownLatch.await();            Thread.sleep(100L);        }    }     private void modifyUser(final CountDownLatch countDownLatch, String threadName, int userId) {        Thread t = new Thread(new Runnable() {            @Override            public void run() {                try {                    String threadName = Thread.currentThread().getName();                    try {                        AnnotationUser5Bean userBean = userMapper.selectById(userId);                        if (null == userBean) {                            return;                        }                        AnnotationUser5Bean newBean = new AnnotationUser5Bean();                        newBean.setName(userBean.getName());                        newBean.setSex(userBean.getSex());                        newBean.setAge(userBean.getAge() + 1);                        newBean.setUserId(userBean.getUserId());                        newBean.setVersion(userBean.getVersion());                        int result = userMapper.updateById(newBean);                        System.out.println("result=" + result + " ==> " + userBean);                    } catch (Exception e) {                        System.err.println(threadName + " " + e.getMessage());                    }                } finally {                    countDownLatch.countDown();                }            }        });        t.setName(threadName);        t.start();    } }

在运行上面代码之前,我们数据库中的记录值如下:

user_idnamesexageversion
1测试00

运行上面程序,数据库记录如下:

user_idnamesexageversion
1测试016

上面代码将执行10次循环操作,每次操作启动两个线程(线程 A 和 线程 B)去修改用户数据。

如果数据没有任何冲突,则用户的年龄应该是 20。但是上面程序运行完成后年龄为 16

这就说明,在线程运行的时候,可能A 刚好修改了version,并没有执行完,就到B线程了,就导致B线程修改失败

感谢各位的阅读,以上就是“MybatisPlus中@Version注解如何使用”的内容了,经过本文的学习后,相信大家对MybatisPlus中@Version注解如何使用这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是编程网,小编将为大家推送更多相关知识点的文章,欢迎关注!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     807人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     351人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     314人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     433人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     221人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯