最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

詳解MybatisPlus中@Version注解的使用

 更新時(shí)間:2022年06月16日 17:05:40   作者:知識(shí)的搬運(yùn)工旺仔  
在MyBatisPlus中,常常使用@Version實(shí)現(xiàn)樂觀鎖,該注解用于字段上面。本文將通過示例詳細(xì)講解@Version注解的使用,感興趣的可以了解一下

1. 簡(jiǎn)單介紹

嗨,大家好,今天給想給大家分享一下關(guān)于Mybatis-plus 的 Service 層的一些方法的使用。今天沒有總結(jié),因?yàn)槎际且恍〢PI沒有什么可以總結(jié)的,直接看著調(diào)用就可以了。

下面我們將介紹 @Version 注解的用法,以及每個(gè)屬性的實(shí)際意義和用法

2. 注解說(shuō)明

在 MyBatis Plus 中,使用 @Version 實(shí)現(xiàn)樂觀鎖,該注解用于字段上面

3. 什么是樂觀鎖

3.1 樂觀鎖簡(jiǎn)介

  • 樂觀鎖(Optimistic Locking)是相對(duì)悲觀鎖而言的,樂觀鎖假設(shè)數(shù)據(jù)一般情況下不會(huì)造成沖突
  • 所以在數(shù)據(jù)進(jìn)行提交更新的時(shí)候,才會(huì)正式對(duì)數(shù)據(jù)的沖突進(jìn)行檢測(cè)
  • 如果發(fā)現(xiàn)沖突了,則返回給用戶錯(cuò)誤的信息,讓用戶決定如何去做
  • 樂觀鎖適用于讀操作多的場(chǎng)景,這樣可以提高程序的吞吐量

3.2 樂觀鎖實(shí)例

存在兩個(gè)線程 A 和 B,分別從數(shù)據(jù)庫(kù)讀取數(shù)據(jù)。執(zhí)行后,線程 A 和 線程 B 的 version 均等于 1。如下圖

線程 A 處理完業(yè)務(wù),提交數(shù)據(jù)。此時(shí),數(shù)據(jù)庫(kù)中該記錄的 version 為 2。如下圖:

線程 B 也處理完業(yè)務(wù)了,提交數(shù)據(jù)。此時(shí),數(shù)據(jù)庫(kù)中的 version 已經(jīng)等于 2,而線程的 version 還是 1。程序給出錯(cuò)誤信息,不允許線程 B 操作數(shù)據(jù)。如下圖:

  • 樂觀鎖機(jī)制采取了更加寬松的加鎖機(jī)制
  • 樂觀鎖是相對(duì)悲觀鎖而言,也是為了避免數(shù)據(jù)庫(kù)幻讀、業(yè)務(wù)處理時(shí)間過長(zhǎng)等原因引起數(shù)據(jù)處理錯(cuò)誤的一種機(jī)制
  • 但樂觀鎖不會(huì)刻意使用數(shù)據(jù)庫(kù)本身的鎖機(jī)制,而是依據(jù)數(shù)據(jù)本身來(lái)保證數(shù)據(jù)的正確性

4. 實(shí)例代碼

本實(shí)例將在前面用到的 user 表上面進(jìn)行。在進(jìn)行之前,現(xiàn)在 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 的樂觀鎖插件,該插件會(huì)自動(dòng)幫我們將 version 加一操作

注意,這里和分頁(yè)操作一樣,需要進(jìn)行配置,如果不配置,@Version是不會(huì)生效的

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;
 
@Configuration
public class MybatisPlusConfig {
 
    @Bean
    public MybatisPlusInterceptor paginationInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        // 樂觀鎖插件
        interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
        return interceptor;
    }
 
}

測(cè)試樂觀鎖代碼,我們創(chuàng)建兩個(gè)線程 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)
@SpringBootTest
class AnnotationDemo5 {
 
    @Autowired
    private AnnotationUser5Mapper userMapper;
 
    @Test
    void contextLoads() throws Exception {
        // 重置數(shù)據(jù)
        AnnotationUser5Bean user5Bean = new AnnotationUser5Bean();
        user5Bean.setUserId(1);
        user5Bean.setAge(0);
        user5Bean.setVersion(0);
        userMapper.updateById(user5Bean);
 
        // 修改數(shù)據(jù)
        for (int i = 0; i < 10; i++) {
            System.out.println("第 " + (i + 1) + " 次修改數(shù)據(jù)");
            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();
    }
 
}

在運(yùn)行上面代碼之前,我們數(shù)據(jù)庫(kù)中的記錄值如下:

user_idnamesexageversion
1測(cè)試00

運(yùn)行上面程序,數(shù)據(jù)庫(kù)記錄如下:

user_idnamesexageversion
1測(cè)試016

1.上面代碼將執(zhí)行10次循環(huán)操作,每次操作啟動(dòng)兩個(gè)線程(線程 A 和 線程 B)去修改用戶數(shù)據(jù)。

2.如果數(shù)據(jù)沒有任何沖突,則用戶的年齡應(yīng)該是 20。但是上面程序運(yùn)行完成后年齡為 16

3.這就說(shuō)明,在線程運(yùn)行的時(shí)候,可能A 剛好修改了version,并沒有執(zhí)行完,就到B線程了,就導(dǎo)致B線程修改失敗

以上就是詳解MybatisPlus中@Version注解的使用的詳細(xì)內(nèi)容,更多關(guān)于MybatisPlus @Version注解的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • eclipse端口被占用問題的解決方法

    eclipse端口被占用問題的解決方法

    這篇文章主要給大家介紹了關(guān)于eclipse端口被占用問題的解決方法,文中通過圖文以及命令代碼介紹的非常詳細(xì),對(duì)遇到這個(gè)問題的朋友們具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2018-07-07
  • SpringBoot如何使用validator框架優(yōu)雅地校驗(yàn)參數(shù)

    SpringBoot如何使用validator框架優(yōu)雅地校驗(yàn)參數(shù)

    文章介紹了如何使用SpringValidation進(jìn)行參數(shù)校驗(yàn),包括引入依賴、@requestBody和@requestParam參數(shù)校驗(yàn)、統(tǒng)一異常處理、分組校驗(yàn)、嵌套校驗(yàn)、自定義校驗(yàn)、業(yè)務(wù)規(guī)則校驗(yàn)以及@Valid和@Validated的區(qū)別,同時(shí),列舉了常用的BeanValidation和HibernateValidator注解
    2025-02-02
  • java內(nèi)部類的那些事兒_讓你一看就弄明白

    java內(nèi)部類的那些事兒_讓你一看就弄明白

    本篇文章介紹了,java內(nèi)部類的那些事兒。需要的朋友參考下
    2013-05-05
  • Java對(duì)類私有變量的暴力反射技術(shù)講解

    Java對(duì)類私有變量的暴力反射技術(shù)講解

    今天小編就為大家分享一篇關(guān)于Java對(duì)類私有變量的暴力反射技術(shù)講解,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2019-03-03
  • SpringMVC攔截器實(shí)現(xiàn)單點(diǎn)登錄

    SpringMVC攔截器實(shí)現(xiàn)單點(diǎn)登錄

    這篇文章主要介紹了SpringMVC攔截器實(shí)現(xiàn)單點(diǎn)登錄,簡(jiǎn)單介紹了springmvc攔截器,單點(diǎn)登錄實(shí)現(xiàn)原理等相關(guān)內(nèi)容,具有一定參考價(jià)值,需要的朋友可以了解下。
    2017-11-11
  • Java實(shí)現(xiàn)去掉字符串重復(fù)字母的方法示例

    Java實(shí)現(xiàn)去掉字符串重復(fù)字母的方法示例

    這篇文章主要介紹了Java實(shí)現(xiàn)去掉字符串重復(fù)字母的方法,涉及java針對(duì)字符串的遍歷、判斷、運(yùn)算等相關(guān)操作技巧,需要的朋友可以參考下
    2017-12-12
  • SpringBoot2.0集成Swagger2訪問404的解決操作

    SpringBoot2.0集成Swagger2訪問404的解決操作

    這篇文章主要介紹了SpringBoot2.0集成Swagger2訪問404的解決操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來(lái)看看吧
    2020-09-09
  • 淺析JAVA_HOME,CLASSPATH和PATH的作用

    淺析JAVA_HOME,CLASSPATH和PATH的作用

    以下是對(duì)JAVA_HOME,CLASSPATH和PATH的作用進(jìn)行了詳細(xì)的分析介紹,需要的朋友可以過來(lái)參考下
    2013-07-07
  • SpringBoot參數(shù)校驗(yàn)的一些實(shí)戰(zhàn)應(yīng)用

    SpringBoot參數(shù)校驗(yàn)的一些實(shí)戰(zhàn)應(yīng)用

    這篇文章主要給大家介紹了關(guān)于SpringBoot參數(shù)校驗(yàn)的一些實(shí)戰(zhàn)應(yīng)用,包括使用內(nèi)置的參數(shù)校驗(yàn)注解、嵌套對(duì)象校驗(yàn)、分組校驗(yàn)以及自定義校驗(yàn)注解,通過這些方法,可以有效地提高系統(tǒng)的穩(wěn)定性和安全性,需要的朋友可以參考下
    2024-11-11
  • java處理csv文件上傳示例詳解

    java處理csv文件上傳示例詳解

    這篇文章主要為大家詳細(xì)介紹了java處理csv文件上傳示例,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-12-12

最新評(píng)論

三江| 离岛区| 阳高县| 桑日县| 凤山县| 安陆市| 青铜峡市| 滁州市| 新蔡县| 通海县| 基隆市| 基隆市| 杂多县| 新余市| 桃园县| 余干县| 商水县| 德清县| 阿鲁科尔沁旗| 海安县| 鄂尔多斯市| 若羌县| 郯城县| 犍为县| 南投市| 焦作市| 福贡县| 邻水| 砚山县| 罗城| 湾仔区| 米林县| 巴林右旗| 汉阴县| 天津市| 汉川市| 宜城市| 沾化县| 水城县| 石首市| 逊克县|