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

MyBatisPlus樂觀鎖和悲觀鎖的實現(xiàn)示例

 更新時間:2025年11月30日 15:01:08   作者:222you  
本文主要介紹了MyBatisPlus樂觀鎖和悲觀鎖,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

1.場景

一件商品,成本價是80元,售價是100元。老板先是通知小李,說你去把商品價格增加50元。小 李正在玩游戲,耽擱了一個小時。正好一個小時后,老板覺得商品價格增加到150元,價格太高,可能會影響銷量。又通知小王,你把商品價格降低30元。

此時,小李和小王同時操作商品后臺系統(tǒng)。小李操作的時候,系統(tǒng)先取出商品價格100元;小王  也在操作,取出的商品價格也是100元。小李將價格加了50元,并將100+50=150元存入了數(shù)據(jù)  庫;小王將商品減了30元,并將100-30=70元存入了數(shù)據(jù)庫。是的,如果沒有鎖,小李的操作就 完全被小王的覆蓋了。

現(xiàn)在商品價格是70元,比成本價低10元。幾分鐘后,這個商品很快出售了1千多件商品,老板虧1 萬多。

2.樂觀鎖和悲觀鎖

上面的故事,如果是樂觀鎖,小王保存價格前,會檢查下價格是否被人修改過了。如果被修改過 了,則重新取出的被修改后的價格,  150元,這樣他會將120元存入數(shù)據(jù)庫。

如果是悲觀鎖,小李取出數(shù)據(jù)后,小王只能等小李操作完之后,才能對價格進行操作,也會保證 最終的價格是120元。

3.樂觀鎖實現(xiàn)

添加插件:

    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        // 添加分頁插件
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));

        // 添加樂觀鎖插件
        interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
        return interceptor;
    }

創(chuàng)建表:

CREATE TABLE t_product
(
    id BIGINT(20) NOT NULL COMMENT '主鍵ID',
    NAME VARCHAR(30) NULL DEFAULT NULL COMMENT '商品名稱 ',
    price INT(11) DEFAULT 0 COMMENT '價格 ',
    VERSION INT(11) DEFAULT 0 COMMENT '樂觀鎖版本號 ',
    PRIMARY KEY (id)
);

添加數(shù)據(jù):

INSERT INTO t_product (id, NAME, price) VALUES (1, '外星人筆記本 ', 100);

如圖:

編寫實體類:

package com.qcby.entity;

import com.baomidou.mybatisplus.annotation.Version;
import lombok.Data;

@Data
public class Product {
    private Long id;
    private String name;
    private Integer price;

    @Version
    private Integer version;
}

mapper:

package com.qcby.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.qcby.entity.Product;
import org.springframework.stereotype.Repository;

@Repository
public interface ProductMapper extends BaseMapper<Product> {
}

測試:

package com.qcby;

import com.qcby.entity.Product;
import com.qcby.mapper.ProductMapper;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
public class MybatisTestOptimisticLock {

    @Autowired
    private ProductMapper productMapper;

    @Test
    public void testOptimisticLock() {
        // 小李查詢商品信息
        Product productLi = productMapper.selectById(1L);
        System.out.println("小李查詢價格: " + productLi.getPrice() + ", 版本: " + productLi.getVersion());

        // 小王查詢商品信息
        Product productWang = productMapper.selectById(1L);
        System.out.println("小王查詢價格: " + productWang.getPrice() + ", 版本: " + productWang.getVersion());

        // 小李修改價格 +50
        productLi.setPrice(productLi.getPrice() + 50);
        int resultLi = productMapper.updateById(productLi);
        System.out.println("小李修改結(jié)果: " + resultLi);

        if (resultLi > 0) {
            Product afterLi = productMapper.selectById(1L);
            System.out.println("小李修改后價格: " + afterLi.getPrice() + ", 版本: " + afterLi.getVersion());
        }

        // 小王修改價格 -30
        productWang.setPrice(productWang.getPrice() - 30);
        int resultWang = productMapper.updateById(productWang);
        System.out.println("小王修改結(jié)果: " + resultWang);

        if (resultWang == 0) {
            // 小王修改失敗,需要重新嘗試
            System.out.println("小王修改失敗,版本已變更,需要重新操作");
            Product newProductWang = productMapper.selectById(1L);
            newProductWang.setPrice(newProductWang.getPrice() - 30);
            resultWang = productMapper.updateById(newProductWang);
            System.out.println("小王重試結(jié)果: " + resultWang);
        }

        // 最終價格
        Product finalProduct = productMapper.selectById(1L);
        System.out.println("最終價格: " + finalProduct.getPrice() + ", 版本: " + finalProduct.getVersion());
    }
}

實際流程:

1. 小李查詢: SELECT id,name,price,version FROM t_product WHERE id=1
   結(jié)果: price=100, version=0

2. 小王查詢: SELECT id,name,price,version FROM t_product WHERE id=1
   結(jié)果: price=100, version=0

3. 小李更新: UPDATE t_product SET name=?, price=150, version=1
           WHERE id=1 AND version=0
   成功: version變?yōu)?

4. 小王更新: UPDATE t_product SET name=?, price=70, version=1
           WHERE id=1 AND version=0
   失敗: version條件不匹配

5. 小王重試: 重新查詢 price=150, version=1
           更新: SET price=120, version=2 WHERE id=1 AND version=1
   成功

6. 最終價格: 120元 (正確的價格)

4.悲觀鎖

悲觀鎖總是假設(shè)最壞的情況,認(rèn)為共享資源每次被訪問的時候就會出現(xiàn)問題(比如共享數(shù)據(jù)被修改),所以每次在獲取資源操作的時候都會上鎖,這樣其他線程想拿到這個資源就會阻塞直到鎖被上一個持有者釋放。也就是說,共享資源每次只給一個線程使用,其它線程阻塞,用完后再把資源轉(zhuǎn)讓給其它線程。

到此這篇關(guān)于MyBatisPlus樂觀鎖和悲觀鎖的實現(xiàn)示例的文章就介紹到這了,更多相關(guān)MyBatisPlus樂觀鎖和悲觀鎖內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • jvm crash的崩潰日志詳細分析及注意點

    jvm crash的崩潰日志詳細分析及注意點

    本篇文章主要介紹了jvm crash的崩潰日志詳細分析及注意點。具有很好的參考價值,下面跟著小編一起來看下吧
    2017-04-04
  • JAVA springboot如何開啟倆端口

    JAVA springboot如何開啟倆端口

    這篇文章主要介紹了JAVA springboot如何開啟倆端口問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2025-03-03
  • 使用SpringSecurity設(shè)置角色和權(quán)限的注意點

    使用SpringSecurity設(shè)置角色和權(quán)限的注意點

    這篇文章主要介紹了使用SpringSecurity設(shè)置角色和權(quán)限的注意點,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • 通過原理解析Spring mvc的內(nèi)置編碼過濾器

    通過原理解析Spring mvc的內(nèi)置編碼過濾器

    這篇文章通過原理主要給大家解析了關(guān)于Spring mvc的內(nèi)置編碼過濾器的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起看看吧。
    2017-09-09
  • 使用springboot對外部靜態(tài)資源文件的處理操作

    使用springboot對外部靜態(tài)資源文件的處理操作

    這篇文章主要介紹了使用springboot對外部靜態(tài)資源文件的處理操作,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • 詳解SpringBoot如何實現(xiàn)統(tǒng)一后端返回格式

    詳解SpringBoot如何實現(xiàn)統(tǒng)一后端返回格式

    在前后端分離的項目中后端返回的格式一定要友好,不然會對前端的開發(fā)人員帶來很多的工作量。那么SpringBoot如何做到統(tǒng)一的后端返回格式呢?本文將為大家詳細講講
    2022-04-04
  • Java高級之HashMap中的entrySet()方法使用

    Java高級之HashMap中的entrySet()方法使用

    這篇文章主要介紹了Java高級之HashMap中的entrySet()方法使用,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-03-03
  • 解決Java?properties文件里面如何寫"\"的問題

    解決Java?properties文件里面如何寫"\"的問題

    由于properties使用“\”相當(dāng)于是java的轉(zhuǎn)義符,如果想要寫出\的效果,只需修改相應(yīng)的寫法即可,對java?properties文件里的"\"寫法感興趣的朋友一起看看吧
    2022-04-04
  • 詳解SpringMVC的類型轉(zhuǎn)換及驗證方法

    詳解SpringMVC的類型轉(zhuǎn)換及驗證方法

    在本篇文章里面我們給大家詳細分析了SpringMVC的類型轉(zhuǎn)換及驗證方法的相關(guān)知識,對此有需要的朋友們學(xué)習(xí)下吧。
    2018-10-10
  • Java版坦克大戰(zhàn)游戲源碼示例

    Java版坦克大戰(zhàn)游戲源碼示例

    本篇文章主要介紹了Java版坦克大戰(zhàn)游戲源碼示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-10-10

最新評論

许昌县| 珲春市| 綦江县| 洛浦县| 得荣县| 磴口县| 本溪市| 大厂| 策勒县| 财经| 临颍县| 清远市| 遂昌县| 正镶白旗| 额尔古纳市| 富民县| 长阳| 漾濞| 平顺县| 措美县| 盐城市| 额尔古纳市| 藁城市| 西充县| 榆树市| 双桥区| 永康市| 西盟| 临泉县| 壶关县| 凤冈县| 伊金霍洛旗| 曲周县| 高清| 信丰县| 长顺县| 嘉善县| 仁化县| 中卫市| 西乌珠穆沁旗| 尖扎县|