为了账号安全,请及时绑定邮箱和手机立即绑定

请教各位前辈关于高并发下生成订单唯一流水号的方法?附己见

请教各位前辈关于高并发下生成订单唯一流水号的方法?附己见

Cats萌萌 2019-04-13 08:36:11
各位前辈们晚上好,之所以发这个帖子是因为之前在项目中用的生成随机流水号的工具类有问题,出现了重号,比如订单1的订单号是123,订单2的订单号也是123。所使用的生成随机号码的规则为:类别(比如OD)+年月日时分秒+随机3位数字可是我感觉随机这东西就是在碰运气啊,就算我加上毫秒,也有可能出现重号,毕竟3位数字太少,加多几位数字也一样,于事无补。我能想到的解决方法如下:1、UUID,可是32位太长了,用不上啊……2、每次生成订单号后查一下数据库是否已经有该订单号,有的话则重新生成,这个感觉不靠谱,太慢了……3、创建一个编号表,使用主键作为订单编号的一部分,因为主键自增是唯一的,可是用这个的话将来一旦量大了,那订单编号的位数就会越来越大,无法控制了其他的方法没有想到更好的了,希望前辈们可以指导一下如何解决,谢谢前辈们了
查看完整描述

2 回答

?
繁华开满天机

TA贡献1816条经验 获得超4个赞

以下要素视情况组合
日期
秒数/毫秒数
机器hash(不同机器不重复)
PID(不同进程不重复)
用户ID
db自增(性能较差)
redis自增(性能不错,需要redis,有故障风险)
类似mongodb的“单进程单秒内”的自增(性能最高)
另外,db/redis自增均可考虑跳步&缓存来降低压力(每次自增10/50/100回来后缓存在本地,本地的用完再去拿)
                            
查看完整回答
反对 回复 2019-04-13
?
DIEA

TA贡献1820条经验 获得超2个赞

各位前辈们好,我有一个想法不知道是否可行:
1、创建一个序列号表,只有一行数据,为序列号的值
2、生成序列号时,每次读取该表,从该表中读取该行数据,语句为:
SELECTSERIAL_NUMFROMSERIAL_TABLEWHEREID=1FORUPDATE;
3、每次读取的时候给该行使用FORUPDATE上锁,读取完以后使用以下语句:
UPDATESERIAL_TABLESETSERIAL_NUM=SERIAL_NUM+1WHEREID=1;
COMMIT;
4、释放行锁,不知道这样是否可行,欸……
                            
查看完整回答
反对 回复 2019-04-13
  • 2 回答
  • 0 关注
  • 1124 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信