mybatis-plus id在高并发下出现重复

x33g5p2x  于9个月前 转载在 其他  
字(1.4k)|赞(0)|评价(0)|浏览(325)

mybaits-plus ASSIGN_ID生成

id生成策略 在分布式高并发环境下出现重复id https://github.com/baomidou/mybatis-plus/issues/3077
mybatis-plus 对@TableId(type = IdType.ASSIGN_ID)生成默认使用com.baomidou.mybatisplus.core.toolkit.Sequence,这个类是雪花算法的实现,在该实现中workid,datacenterid是根据网卡硬件地址生成,而部署在docker容器内的应用读取不到宿主机的硬件地址

什么是雪花算法

雪花算法是Twitter开源的一种全局唯一ID生成算法,它可以生成一个64位的整数ID。在雪花算法中,workerid是一个重要的参数,用于标识不同的机器。需要保证在不同的机器之间是唯一的,通常可以通过MAC地址或者IP地址来生成workerid。

解决方案

解决思路是,只要workid,datacenterid中组合确保在所有节点中唯一就解决问题。
下面选用了redis的自增值解决,当然也可以使用zookeeper、mysql等等,从已有的组件中选就好
com.baomidou.mybatisplus.core.toolkit.Sequence#getMaxWorkerId

  1. /**
  2. * 通过redis自增初始化的snowflake
  3. */
  4. @Component
  5. public class SnowflakeUtil {
  6. private volatile Snowflake snowflake;
  7. @Resource
  8. private RedissonClient redissonClient;
  9. public long nextId() {
  10. return getSnowflake().nextId();
  11. }
  12. public String nextIdStr() {
  13. return String.valueOf(nextId());
  14. }
  15. public Snowflake getSnowflake() {
  16. if (snowflake == null) {
  17. synchronized (SnowflakeUtil.class) {
  18. if (snowflake == null) {
  19. long workId = redissonClient.getAtomicLong("snowflake:worker").getAndIncrement();
  20. snowflake = IdUtil.createSnowflake(workId % 32, 1);
  21. }
  22. }
  23. }
  24. return snowflake;
  25. }
  26. }
  27. /**
  28. * 替换mybatis-plus ASSIGN_ID的生成器
  29. */
  30. @Component
  31. public class IdGenerator implements IdentifierGenerator {
  32. private final SnowflakeUtil snowflakeUtil;
  33. public IdGenerator(SnowflakeUtil snowflakeUtil) {
  34. this.snowflakeUtil = snowflakeUtil;
  35. }
  36. @Override
  37. public Number nextId(Object entity) {
  38. return snowflakeUtil.nextId();
  39. }
  40. }

本文来自博客园,作者:IAyue,转载请注明原文链接:https://www.cnblogs.com/zmj-pr/p/16856864.html

相关文章