asp按时间自动递增编号_Java秒杀系统实战系列-分布式唯一ID生成订单编号
本文是“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生成订单编号的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 怎样做到不浪费食品调味料?
- 下一篇: 鸡蛋如何取蛋清?