asp按时间自动递增编号_Java秒杀系统实战系列-分布式唯一ID生成订单编号
本文是“Java秒殺系統(tǒng)實戰(zhàn)系列文章”的第七篇,在本文中我們將重點介紹 “在高并發(fā),如秒殺的業(yè)務(wù)場景下如何生成全局唯一、趨勢遞增的訂單編號”,我們將介紹兩種方法,一種是傳統(tǒng)的采用隨機數(shù)生成的方式,另外一種是采用當前比較流行的“分布式唯一ID生成算法-雪花算法”來實現(xiàn)。
在上一篇文章,我們完成了商品秒殺業(yè)務(wù)邏輯的代碼實戰(zhàn),在該代碼中,我們還實現(xiàn)了“當用戶秒殺成功后,需要在數(shù)據(jù)庫表中為其生成一筆秒殺成功的訂單記錄”的功能,其對應(yīng)的代碼如下所示:
//通用的方法-記錄用戶秒殺成功后生成的訂單-并進行異步郵件消息的通知private void commonRecordKillSuccessInfo(ItemKillkill, Integer userId) throws Exception{ //TODO:記錄搶購成功后生成的秒殺訂單記錄 ItemKillSuccess entity=new ItemKillSuccess(); //此處為訂單編號的生成邏輯 String orderNo=String.valueOf(snowFlake.nextId()); //entity.setCode(RandomUtil.generateOrderCode()); //傳統(tǒng)時間戳+N位隨機數(shù) 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); //其他邏輯省略 }}在該實現(xiàn)邏輯中,其核心要點在于“在高并發(fā)的環(huán)境下,如何高效的生成訂單編號”,那么如何才算是高效呢?Debug認為應(yīng)該滿足以下兩點:
1、保證訂單編號的生成邏輯要快、穩(wěn)定,減少時延;
2、要保證生成的訂單編號全局唯一、不重復、趨勢遞增、有時序性。
下面,我們采用兩種方式來生成“訂單編號”,并自己寫一個多線程的程序模擬生成的訂單編號是否滿足條件。
值得一提的是,為了能直觀的觀察多線程并發(fā)生成的訂單編號是否具有唯一性、趨勢遞增,在這里Debug借助了一張數(shù)據(jù)庫表 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;從該數(shù)據(jù)庫表數(shù)據(jù)結(jié)構(gòu)定義語句中可以看出,我們設(shè)定了 訂單編號字段code 為唯一!所以如果高并發(fā)多線程生成的訂單編號出現(xiàn)重復,那么在插入數(shù)據(jù)庫表的時候必然會出現(xiàn)錯誤。
下面,首先開始我們的第一種方式吧:基于隨機數(shù)的方式生成訂單編號。
(1)首先是建立一個Thread類,其run方法的執(zhí)行邏輯為生成訂單編號,并將生成的訂單編號插入數(shù)據(jù)庫表中,其代碼如下所示:
/** * 隨機數(shù)生成的方式-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() { //生成訂單編號并插入數(shù)據(jù)庫 RandomCode entity=new RandomCode(); entity.setCode(RandomUtil.generateOrderCode()); randomCodeMapper.insertSelective(entity); }}其中,RandomUtil.generateOrderCode()的生成邏輯是借助ThreadLocalRandom來實現(xiàn)的,其完整的源代碼如下所示:
/** * 隨機數(shù)生成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為隨機數(shù)流水號 return dateFormatOne.format(DateTime.now().toDate()) + generateNumber(4); } //N為隨機數(shù)流水號 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控制器 中開發(fā)一個請求方法,目的正是用來模擬前端高并發(fā)觸發(fā)產(chǎn)生多線程并生成訂單編號的邏輯,在這里我們暫且用1000個線程進行模擬,其源代碼如下所示:
@Autowiredprivate RandomCodeMapper randomCodeMapper;//測試在高并發(fā)下多線程生成訂單編號-傳統(tǒng)的隨機數(shù)生成方法@RequestMapping(value ="/code/generate/thread總結(jié)
以上是生活随笔為你收集整理的asp按时间自动递增编号_Java秒杀系统实战系列-分布式唯一ID生成订单编号的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 怎样做到不浪费食品调味料?
- 下一篇: java 写文件 异常 磁盘空间满_系统