欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Mybatis-Plus使用ID_WORKER生成主鍵id重復(fù)的解決方法

 更新時(shí)間:2022年07月08日 10:16:58   作者:BUG指揮官  
本文主要介紹了Mybatis-Plus使用ID_WORKER生成主鍵id重復(fù)的解決方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

問題描述

目前項(xiàng)目使用的id是mybatis-plus 內(nèi)置的主鍵生成策略 ID_WORKER ,最近測(cè)試在做性能壓測(cè),部署架構(gòu)是單服務(wù)集群的部署方式,然后就發(fā)現(xiàn)了id重復(fù)的異常,異常如下

問題分析

首先分析的是id生成是不是就是重復(fù)了,先關(guān)掉其中一臺(tái)機(jī)器,單機(jī)跑,這個(gè)時(shí)候發(fā)現(xiàn)壓到1000的并發(fā)都沒有出現(xiàn)過id重復(fù),這個(gè)說明單機(jī)情況下不存在id重復(fù)問題,說明只有集群的情況下才會(huì)出現(xiàn)。

再分析一下id生成的幾個(gè)要素,雪花算法的核心能影響到id生成的幾個(gè)因素:1.服務(wù)器時(shí)間2.workId(機(jī)器 ID 部分)3.datacenterId(數(shù)據(jù)標(biāo)識(shí) ID 部分)。先檢查了一下服務(wù)器時(shí)間,都是一樣的,然后再看一下workId的生成,我們先看一下源碼。

public Sequence() {
    this.datacenterId = getDatacenterId(maxDatacenterId);
    this.workerId = getMaxWorkerId(datacenterId, maxWorkerId);
}
//獲取workerId
protected static long getMaxWorkerId(long datacenterId, long maxWorkerId) {
        StringBuilder mpid = new StringBuilder();
        mpid.append(datacenterId);
        //代表正在運(yùn)行的Java虛擬機(jī)的名稱。
        String name = ManagementFactory.getRuntimeMXBean().getName();
        if (StringUtils.isNotEmpty(name)) {
            /*
             * GET jvmPid
             */
            mpid.append(name.split(StringPool.AT)[0]);
        }
        /*
         * MAC + PID 的 hashcode 獲取16個(gè)低位
         */
        return (mpid.toString().hashCode() & 0xffff) % (maxWorkerId + 1);
    }

這里生成的workerId主要核心影響就是獲取運(yùn)行的虛擬機(jī)名稱,現(xiàn)在猜測(cè)就是有可能是由于兩臺(tái)機(jī)的虛擬機(jī)名稱可能一樣,導(dǎo)致拿到的workerId一樣。這個(gè)沒有具體去驗(yàn)證,猜測(cè)是這樣的。那我們嘗試修改一下這個(gè)workerId的值。

問題解決

1.先設(shè)置workerId為隨機(jī)數(shù),這樣保證每個(gè)機(jī)器部署的時(shí)候拿到的都是隨機(jī)數(shù)

# 設(shè)置隨機(jī)
mybatis-plus.global-config.worker-id: ${random.int}

這里你啟動(dòng)項(xiàng)目的時(shí)候會(huì)發(fā)現(xiàn)一個(gè)異常

異常很明顯,這里的worer id 必選小于31,那我們就需要修改一下隨機(jī)數(shù)

# 設(shè)置隨機(jī)
mybatis-plus.global-config.worker-id: ${random.int(1,31)}

這個(gè)時(shí)候我們先看一下我們?cè)O(shè)置參數(shù)有沒有生效,為了比較明顯看到效果,我們直接設(shè)置worker-id為一個(gè)固定值20,再斷點(diǎn)看一下,我們找到com.baomidou.mybatisplus.core.toolkit.IdWorker
這個(gè)核心類,獲取id的核心方法是com.baomidou.mybatisplus.core.toolkit.IdWorker#getId
,那我們就在這里加一個(gè)斷點(diǎn)看下

public class IdWorker {
 
    /**
     * 主機(jī)和進(jìn)程的機(jī)器碼
     */
    private static Sequence WORKER = new Sequence();
    //獲取id
    public static long getId() {
        return WORKER.nextId();
    }
 
    public static String getIdStr() {
        return String.valueOf(WORKER.nextId());
    }
 
    /**
     * <p>
     * 有參構(gòu)造器
     * </p>
     *
     * @param workerId     工作機(jī)器 ID
     * @param datacenterId 序列號(hào)
     */
    public static void initSequence(long workerId, long datacenterId) {
        WORKER = new Sequence(workerId, datacenterId);
    }
 
    /**
     * <p>
     * 使用ThreadLocalRandom獲取UUID獲取更優(yōu)的效果 去掉"-"
     * </p>
     */
    public static String get32UUID() {
        ThreadLocalRandom random = ThreadLocalRandom.current();
        return new UUID(random.nextLong(), random.nextLong()).toString().replace(StringPool.DASH, StringPool.EMPTY);
    }
 
}

斷點(diǎn)后的結(jié)果是:

這個(gè)時(shí)候看到workerId沒有生效,我們繼續(xù)分析下源碼。

項(xiàng)目啟動(dòng)的時(shí)候,mybatis-plus 會(huì)調(diào)用一個(gè)com.baomidou.mybatisplus.core.MybatisConfiguration#init
方法來初始化配置信息,我們看下代碼

public void init(GlobalConfig globalConfig) {
        // 初始化 Sequence
    //這里需要同時(shí)設(shè)置workerId和datacenterId
        if (null != globalConfig.getWorkerId()
            && null != globalConfig.getDatacenterId()) {
            IdWorker.initSequence(globalConfig.getWorkerId(), globalConfig.getDatacenterId());
        }
        // 打印 Banner
        if (globalConfig.isBanner()) {
            System.out.println(" _ _   |_  _ _|_. ___ _ |    _ ");
            System.out.println("| | |\\/|_)(_| | |_\\  |_)||_|_\\ ");
            System.out.println("     /               |         ");
            System.out.println("                        "+MybatisPlusVersion.getVersion()+" ");
        }
    }

我們發(fā)現(xiàn)workerId和datacenterId必須同時(shí)設(shè)置才會(huì)獲取我們?cè)O(shè)置的值。

那我們就修改配置一下

# 設(shè)置隨機(jī)
mybatis-plus.global-config.worker-id: ${random.int(1,31)}
mybatis-plus.global-config.datacenter-id: ${random.int(1,31)}

這樣設(shè)置以后發(fā)現(xiàn)終于生效了,然后部署一下,問題終于解決了。這里問題雖然解決了,但是workerId重復(fù)其實(shí)沒有實(shí)際驗(yàn)證過,如果有驗(yàn)證過的同學(xué)歡迎留言。值得一提的是現(xiàn)在mybatis-plus官方以及不提倡使用ID_WORKER和ID_WORKER_STR策略生成id了。

到此這篇關(guān)于Mybatis-Plus使用ID_WORKER生成主鍵id重復(fù)的解決方法的文章就介紹到這了,更多相關(guān)Mybatis-Plus ID_WORKER生成主鍵id內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 詳解Java如何利用數(shù)字描述更多的信息

    詳解Java如何利用數(shù)字描述更多的信息

    在數(shù)據(jù)庫(kù)里面?,通常我們會(huì)用數(shù)字的遞進(jìn)來描述狀態(tài)等信息?,?但是如果想進(jìn)行更復(fù)雜的操作?,?就有必要對(duì)二進(jìn)制有一定理解了。本文就來趣味性的探討一下?,?如何通過更少的空間描述更多的信息
    2022-09-09
  • 基于IDEA創(chuàng)建SpringMVC項(xiàng)目流程圖解

    基于IDEA創(chuàng)建SpringMVC項(xiàng)目流程圖解

    這篇文章主要介紹了基于IDEA創(chuàng)建SpringMVC項(xiàng)目流程圖解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-10-10
  • 說一說java關(guān)鍵字final和transient

    說一說java關(guān)鍵字final和transient

    這篇文章主要和大家說一說java關(guān)鍵字final和transient,感興趣的小伙伴們可以參考一下
    2016-06-06
  • SpringBoot在RequestBody中使用枚舉參數(shù)案例詳解

    SpringBoot在RequestBody中使用枚舉參數(shù)案例詳解

    這篇文章主要介紹了SpringBoot在RequestBody中使用枚舉參數(shù)案例詳解,本篇文章通過簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-09-09
  • Springboot配置圖片虛擬映射示例代碼

    Springboot配置圖片虛擬映射示例代碼

    這篇文章主要給大家介紹了關(guān)于Springboot配置圖片虛擬映射的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用springboot具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2021-11-11
  • java 2d畫圖示例分享(用java畫圖)

    java 2d畫圖示例分享(用java畫圖)

    這篇文章主要介紹了java 2D畫圖示例(用java畫圖),需要的朋友可以參考下
    2014-04-04
  • Sa-Token記住我模式實(shí)現(xiàn)七天免登錄

    Sa-Token記住我模式實(shí)現(xiàn)七天免登錄

    這篇文章主要為大家介紹了Sa-Token記住我模式實(shí)現(xiàn)七天免登錄示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-07-07
  • 服務(wù)器CPU高居不下,JAVA線程占用排查方式

    服務(wù)器CPU高居不下,JAVA線程占用排查方式

    這篇文章主要介紹了服務(wù)器CPU高居不下,JAVA線程占用排查方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-09-09
  • Java如何通過反射獲取私有構(gòu)造、私有對(duì)象、私有字段、私有方法

    Java如何通過反射獲取私有構(gòu)造、私有對(duì)象、私有字段、私有方法

    這篇文章主要介紹了Java如何通過反射獲取私有構(gòu)造、私有對(duì)象、私有字段、私有方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • SpringSecurity中的表單認(rèn)證詳細(xì)解析

    SpringSecurity中的表單認(rèn)證詳細(xì)解析

    這篇文章主要介紹了SpringSecurity中的表單認(rèn)證詳細(xì)解析,在上一篇文章中,我們初步引入了?Spring?Security,并使用其默認(rèn)生效的?HTTP?基本認(rèn)證保護(hù)?URL?資源,在本篇文章中我們使用表單認(rèn)證來保護(hù)?URL?資源,需要的朋友可以參考下
    2023-12-12

最新評(píng)論