本文是“Java秒杀系统实战系列文章”的第七篇,在本文中我们将重点介绍 “在高并发,如秒杀的业务场景下如何生成全局唯一、趋势递增的订单编号”,我们将介绍两种方法,一种是传统的采用随机数生成的方式,另外一种是采用当前比较流行的“分布式唯一ID生成算法-雪花算法”来实现。

在上一篇文章,我们完成了商品秒杀业务逻辑的代码实战,在该代码中,我们还实现了“当用户秒杀成功后,需要在数据库表中为其生成一笔秒杀成功的订单记录”的功能,其对应的代码如下所示:

//通用的方法-记录用户秒杀成功后生成的订单-并进行异步邮件消息的通知private void commonRecordKillSuccessInfo(ItemKillkill, Integer userId) throws Exception{ //TODO:记录抢购成功后生成的秒杀订单记录 ItemKillSuccess entity=new ItemKillSuccess(); //此处为订单编号的生成逻辑 String orderNo=String.valueOf(snowFlake.nextId()); //entity.setCode(RandomUtil.generateOrderCode()); //传统时间戳+N位随机数 entity.setCode(orderNo);//雪花算法 entity.setItemId(kill.getItemId()); entity.setKillId(kill.getId()); entity.setUserId(userId.toString()); entity.setStatus(SysConstant.OrderStatus.SuccessNotPayed.getCode().byteValue()); entity.setCreateTime(DateTime.now().toDate()); //TODO:学以致用,举一反三 -> 仿照单例模式的双重检验锁写法 if (itemKillSuccessMapper.countByKillUserId(kill.getId(),userId)<= 0){ intres=itemKillSuccessMapper.insertSelective(entity); //其他逻辑省略 }}

在该实现逻辑中,其核心要点在于“在高并发的环境下,如何高效的生成订单编号”,那么如何才算是高效呢?Debug认为应该满足以下两点:

1、保证订单编号的生成逻辑要快、稳定,减少时延;

2、要保证生成的订单编号全局唯一、不重复、趋势递增、有时序性。

下面,我们采用两种方式来生成“订单编号”,并自己写一个多线程的程序模拟生成的订单编号是否满足条件。

值得一提的是,为了能直观的观察多线程并发生成的订单编号是否具有唯一性、趋势递增,在这里Debug借助了一张数据库表 random_code来存储生成的订单编号,其DDL如下所示:

CREATE TABLE `random_code` ( `id`int(11) NOT NULL AUTO_INCREMENT, `code`varchar(255) DEFAULT NULL, PRIMARY KEY(`id`), UNIQUE KEY`idx_code` (`code`) USING BTREE) ENGINE=InnoDB DEFAULT CHARSET=utf8;

从该数据库表数据结构定义语句中可以看出,我们设定了 订单编号字段code 为唯一!所以如果高并发多线程生成的订单编号出现重复,那么在插入数据库表的时候必然会出现错误。

下面,首先开始我们的第一种方式吧:基于随机数的方式生成订单编号。

(1)首先是建立一个Thread类,其run方法的执行逻辑为生成订单编号,并将生成的订单编号插入数据库表中,其代码如下所示:

/** * 随机数生成的方式-Thread * @Author:debug (SteadyJack) * @Date:2019/7/11 10:30 **/public class CodeGenerateThread implementsRunnable{ private RandomCodeMapper randomCodeMapper;  public CodeGenerateThread(RandomCodeMapper randomCodeMapper) { this.randomCodeMapper = randomCodeMapper; }  @Override public void run() { //生成订单编号并插入数据库 RandomCode entity=new RandomCode(); entity.setCode(RandomUtil.generateOrderCode()); randomCodeMapper.insertSelective(entity); }}

其中,RandomUtil.generateOrderCode()的生成逻辑是借助ThreadLocalRandom来实现的,其完整的源代码如下所示:

/** * 随机数生成util * @Author:debug (SteadyJack) * @Date:2019/6/20 21:05 **/public class RandomUtil { private static final SimpleDateFormat dateFormatOne=newSimpleDateFormat("yyyyMMddHHmmssSS"); private static final ThreadLocalRandom random=ThreadLocalRandom.current(); //生成订单编号-方式一 public static String generateOrderCode(){ //TODO:时间戳+N为随机数流水号 return dateFormatOne.format(DateTime.now().toDate()) + generateNumber(4); } //N为随机数流水号 public static String generateNumber(final int num){ StringBuffer sb=new StringBuffer(); for(int i=1;i<=num;i++){ sb.append(random.nextInt(9)); } return sb.toString(); }}

(2)紧接着是在 BaseController控制器 中开发一个请求方法,目的正是用来模拟前端高并发触发产生多线程并生成订单编号的逻辑,在这里我们暂且用1000个线程进行模拟,其源代码如下所示:

@Autowiredprivate RandomCodeMapper randomCodeMapper;//测试在高并发下多线程生成订单编号-传统的随机数生成方法@RequestMapping(value ="/code/generate/thread

asp按时间自动递增编号_Java秒杀系统实战系列-分布式唯一ID生成订单编号相关推荐

  1. java 唯一编号_Java秒杀系统实战系列~分布式唯一ID生成订单编号

    摘要: 本篇博文是"Java秒杀系统实战系列文章"的第七篇,在本博文中我们将重点介绍 "在高并发,如秒杀的业务场景下如何生成全局唯一.趋势递增的订单编号",我们 ...

  2. Java秒杀系统实战系列~分布式唯一ID生成订单编号

    摘要: 本篇博文是"Java秒杀系统实战系列文章"的第七篇,在本博文中我们将重点介绍 "在高并发,如秒杀的业务场景下如何生成全局唯一.趋势递增的订单编号",我们 ...

  3. sql判断时间大于0点_Java秒杀系统实战系列-数据库级别Sql的优化与代码的调整

    本文是"Java秒杀系统实战系列文章"的第十三篇,从本篇文章开始我们将进入"秒杀代码优化"环节,本文将首先从数据库级别Sql的优化入手,结合调整秒杀相关的部分核 ...

  4. sql取系统时间减一小时_Java秒杀系统实战系列-整体业务流程介绍与数据库设计...

    本篇文章是"Java秒杀系统实战系列文章"的第三篇,本文将主要介绍秒杀系统的整体业务流程,并根据相应的业务流程进行数据库设计,最终采用Mybatis逆向工程生成相应的实体类Enti ...

  5. java设计前期工作基础和存在的困难_Java秒杀系统实战系列-基于Redisson的分布式锁优化秒杀逻辑...

    本文是"Java秒杀系统实战系列文章"的第十五篇,本文我们将借助综合中间件Redisson优化"秒杀系统中秒杀的核心业务逻辑",解决Redis的原子操作在优化秒 ...

  6. java 秒杀代码_Java秒杀系统实战系列~商品秒杀代码实战

    摘要: 本篇博文是"Java秒杀系统实战系列文章"的第六篇,本篇博文我们将进入整个秒杀系统核心功能模块的代码开发,即"商品秒杀"功能模块的代码实战. 内容: & ...

  7. java 模块 分工_Java秒杀系统实战系列~构建SpringBoot多模块项目

    摘要:本篇博文是"Java秒杀系统实战系列文章"的第二篇,主要分享介绍如何采用IDEA,基于SpringBoot+SpringMVC+Mybatis+分布式中间件构建一个多模块的项 ...

  8. ieee39节点系统介绍_Java秒杀系统实战系列-基于ZooKeeper的分布式锁优化秒杀逻辑...

    本文是"Java秒杀系统实战系列文章"的第十六篇,本文我们将继续秒杀系统的优化之路,采用统一协调调度中心中间件ZooKeeper控制秒杀系统中高并发多线程对于共享资源~代码块的并发 ...

  9. Java秒杀系统实战系列~RabbitMQ死信队列处理超时未支付的订单(转)

    转自: https://juejin.cn/post/6844903903130042376 文末有源代码,非常棒 摘要: 本篇博文是"Java秒杀系统实战系列文章"的第十篇,本篇 ...

最新文章

  1. 干货|(DL~3)deep learning中一些层的介绍
  2. 放弃在每日站会上按成员逐个发言
  3. CSS选取第n个元素 :nth-child()
  4. k8s 查看mysql 日志_k8s 使用 Init Container 确保依赖的服务已经启动
  5. Python学习笔记-猜数字游戏(学习语法)
  6. git clone 出现fatal: unable to access ‘https://github 类错误解决方法
  7. Python并发编程Futures
  8. 删除StringBuilder的最后一个字符?
  9. Luogu2564 [SCOI2009]生日礼物
  10. 错误提示 - WPS Office 文字 正在运行
  11. elasticsearch-jdbc下载安装
  12. 邮箱登录入口官网是哪个?域名邮箱登录入口展示
  13. 小米电视看普通电视台,只需几步就能轻松解锁
  14. 2021-07-16 转载 - UmiJS应用框架
  15. 免费送!!!CSDN 会员月卡!
  16. godaddy无法修改域名服务器,GoDaddy DNS问题导致域名解析不正常的解决办法
  17. 使用shui文件夹遇到问题总结
  18. 工作流(workflow)参考规范概述
  19. 新三板公司股权激励设计注意事项
  20. matlab的死区环节,基于SIMULINK对非线性系统死区环节进行仿真.doc

热门文章

  1. d06调试详细说明_D06电脑板调试软件使用说明_20100706
  2. pycharm安装scrapy失败_Scrapy ——环境搭配与一个简单的例子
  3. python 代码分块_[代码全屏查看]-python多进程分块读取文件
  4. ping32终端安全管理方案_RFID固定资产管理解决方案,RFID资产管理,RFID手持终端
  5. 乐鑫代理启明云端分享|ESP32 系列教程之四: Windows 搭建 esp-idf 环境
  6. 北大核刊最新版2020_爱尔兰地图(2020版)
  7. micropython是啥 知乎_micropython入门教程
  8. 计算机配置文章,看电脑配置的“两个”小妙招!
  9. deepin卸载了python_Deepin-Linux下python卸载与安装(失败的折腾)
  10. python函数作用域包括局部变量和参数_python函数变量的作用域声明(全局变量和局部变量)...