mybatis-plus idwork,mybatis plus insert 主键

  mybatis-plus idwork,mybatis plus insert 主键

  00-1010问题描述、问题分析和问题解决

  00-1010目前项目中使用的id是mybatis-plus内置的主键生成策略id_WORKER。最近正在进行性能测试,部署架构是单服务集群部署模式。然后,发现重复ID的异常。例外情况如下

  00-1010首先分析id生成是否重复。首先,关闭其中一台机器,在单台机器上运行。这时发现1000的并发中没有id重复。这说明单机情况下不存在id重复问题,只在集群情况下出现。

  在分析了id生成的几个要素后,雪花算法的核心可以影响id生成的几个因素:1。服务器时间2.workId(机器Id部分)3.datacenterId(数据标识ID部分)。先查服务器时间,都是一样的,再看workId的生成。我们先来看看源代码。

  public Sequence(){ this . data centerid=getdata centerid(maxdata centerid);this . workerid=getMaxWorkerId(data centerid,maxWorkerId);}//Get workerid protected static long getmaxworkerid(long data center,long maxworkerid){ string builder mpid=newstring builder();mpid . append(data centerid);//表示正在运行的Java虚拟机的名称。string name=management factory . getruntimemxbean()。getName();if(string utils . isnotempty(name)){/* * GET JVM PID */mpid . append(name . split(string pool。AT)[0]);} /* * MAC PID的hashcode获取16个低位*/return (mpid.tostring()。hashcode()0x ffff)%(maxworkerid 1);}这里生成的workerId的主要核心影响是获取运行虚拟机的名称。现在,猜测是有可能两台机器的虚拟机名称可能相同,从而导致相同的workerId。这个没有具体考证,猜测是这样的。然后让我们尝试修改这个workerId的值。

  00-1010 1.首先将workerId设置为一个随机数,以确保每台机器在部署时都获得一个随机数。

  #设置随机mybatis-plus . global-config . worker-id : $ { random . int }这里你启动项目的时候会发现一个异常.

  显然,这里的worer id必须小于31,所以我们需要修改随机数。

  #设置随机mybatis-plus。global-config . worker-id : $ { random . int(1,31)}这个时候先看看我们的设置参数是否有效。为了更清楚地看到效果,我们直接将worker-id设置为固定值20,然后看一下断点。我们找到了核心类com。baomi dou . mybatisplus . core . toolkit . id worker .获取id的核心方法是com。baomi dou . mybatisplus . core . toolkit . id worker # getid,所以我们在这里加一个断点。

  Class id worker {/* * *主机和进程的机器代码*/private static sequence worker=new sequence();//获取id公共静态long getid(){ return worker . nextid();}公共静态字符串getIdStr() {

   return String.valueOf(WORKER.nextId()); } /** * <p> * 有参构造器 * </p> * * @param workerId 工作机器 ID * @param datacenterId 序列号 */ public static void initSequence(long workerId, long datacenterId) { WORKER = new Sequence(workerId, datacenterId); } /** * <p> * 使用ThreadLocalRandom获取UUID获取更优的效果 去掉"-" * </p> */ public static String get32UUID() { ThreadLocalRandom random = ThreadLocalRandom.current(); return new UUID(random.nextLong(), random.nextLong()).toString().replace(StringPool.DASH, StringPool.EMPTY); } }断点后的结果是:

  

 

  这个时候看到workerId没有生效,我们继续分析下源码。

  项目启动的时候,mybatis-plus 会调用一个com.baomidou.mybatisplus.core.MybatisConfiguration#init方法来初始化配置信息,我们看下代码

  

public void init(GlobalConfig globalConfig) { // 初始化 Sequence //这里需要同时设置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()+" "); } }

我们发现workerId和datacenterId必须同时设置才会获取我们设置的值。

 

  那我们就修改配置一下

  

# 设置随机mybatis-plus.global-config.worker-id: ${random.int(1,31)}mybatis-plus.global-config.datacenter-id: ${random.int(1,31)}

这样设置以后发现终于生效了,然后部署一下,问题终于解决了。这里问题虽然解决了,但是workerId重复其实没有实际验证过,如果有验证过的同学欢迎留言。值得一提的是现在mybatis-plus官方以及不提倡使用ID_WORKER和ID_WORKER_STR策略生成id了。

 

  到此这篇关于Mybatis-Plus使用ID_WORKER生成主键id重复的解决方法的文章就介绍到这了,更多相关Mybatis-Plus ID_WORKER生成主键id内容请搜索盛行IT以前的文章或继续浏览下面的相关文章希望大家以后多多支持盛行IT!

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: