MyBatis-Plus多节点多线程批量插入(insertBatch) 唯一主键ID冲突(Duplicate entry ‘xxxx‘ for key ‘PRIMARY‘)

1、错误日志

2022-09-2014:59:42.182 [Thread-119] ERROR ...ReconcSnapshot - ReconcSnapshotServiceImpl#doReconcSnapshot error!  param={.....} ### Error updating database. Cause: java.sql.SQLIntegrityConstraintViolationException: Duplicate entry '157248371216629087' for key 'PRIMARY' ### The error may exist in com/...SnapshotMapper.java (best guess) ### The error may involve com...SnapshotMapper.insert-Inline ### The error occurred while setting parameters ### SQL: INSERT INTO t_reconc_snapshot ...

官方的标记为这个Bug已修复
https://github.com/baomidou/mybatis-plus/issues/3289#issue-791890470

2、原因分析

在单机单线程使用雪花算法生成的ID,是不会出现这个问题。在集群环境下,特别是在一台机器中使用Docker 部署了多个节点,同时使用多线程批量插入数据,出现唯一主键ID出现的概率非常大。

ID生成规则:

服务器时间
workId(服务器机器ID)
dataCenterId(数据标识ID部分)

3、解决方案

import cn.hutool.core.util.RandomUtil;
import com.baomidou.mybatisplus.core.incrementer.DefaultIdentifierGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
 
@Configuration
public class MybatisPlusConfig {
 
  /**
   * description: 自定义ID主键生成器 <br>
   * date: 2022/6/1 11:38 <br>
   *
   * @return com.baomidou.mybatisplus.core.incrementer.DefaultIdentifierGenerator
   */
  @Bean
  public DefaultIdentifierGenerator defaultIdentifierGenerator() {
    // 以免多线程批量插入,ID主键生成有重复,主键冲突错误
    // 1-31 随机数
    long workerId = RandomUtil.randomLong(1, 31);
    // 1-31 随机数
    long dataCenterId = RandomUtil.randomLong(1, 31);
 
    return new DefaultIdentifierGenerator(workerId, dataCenterId);
  }
}

4、其它配置

MyBatis-Plus 版本 3.5.1,使用Springboot搭建的项目工程。使用MyBatis-Plus中自动生成ID主键,类型为:ASSIGN_ID (使用的雪花算法生成唯一主键ID)。

部署环境:采用一台服务器Docker多节点,多线程批量插入数据。


mybatis-plus:
  global-config:
    #数据库相关配置
    db-config:
      # 主键类型
      id-type: ASSIGN_ID

或者在java中单独配置

@Data
public class ReconcSnapshot implements Serializable {
    //雪花算法生成id
    @TableId(value = "id",type = IdType.ASSIGN_ID)
    private Long       id;
    ...
}

5、参考文章

https://blog.csdn.net/wagnteng/article/details/117064242

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值