求高并发情况下生成唯一订单号解决方案

hehe123456789 2012-04-18 12:04:03
求高并发情况下生成唯一订单号解决方案。。。
...全文
53370 39 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
39 条回复
切换为时间正序
请发表友善的回复…
发表回复
吕津 2014-05-11
  • 打赏
  • 举报
回复
引用 2 楼 mizuho_2006 的回复:
在插入记录时设置订单号为 年月日时分秒+n位随机数 1秒钟不可能有1000个重复的订单号吧
不一定哦
why7282299 2013-11-21
  • 打赏
  • 举报
回复
我说几个实现吧: 1、依赖于数据库的实现比如专门生产ID的表,就算用数据库主见自增长也行这样就保证了唯一性了,而后拿这个之后想怎么用怎么组合反正都是能保持唯一性的。 2、就上面说的guid 方式 3、最推荐的一种,因为这样效率才最快。 既然说道并发,那锁肯定是在所难免的,就拿上面的两种来说,你数据库自增长肯定最终它还 是有锁的机制吧,还得和数据库打交道呢,未必快,第二种呢,guid,他生产底层实现也肯定得用到锁的机制来,而且那么长,说不定生产的更慢呢。 说说第三种吧,毕竟自己生产的,可能只需要生产个1,2,3,4,5的数字序列唯一就行了,那自己写个并发程序说不定会更快。对于并发锁的说法,有悲观锁和乐观锁,那我就觉得乐观锁能实现肯定就比较快, 自己写实现可能比较难写,我也没具体写过,我写我肯定直接一把锁,反正在java中的话,在.net中我不清楚,java中有个并发库API,人java自带乐观锁的实现,效率很高,值得采用。
  • 打赏
  • 举报
回复
作为一个例子,可以借鉴一下MongoDB的机制。它因为高性能而著名,大量并发读写线程都可以支持。而这个数据库真正的读写操作,只有一个线程,根本不并发。它确实是使用了“不并发”的底层机制,来支持高性能并发应用的。

至于为什么能够支持高并发,我懒得说了。我想抠字眼的人应该明白,要理解其机制才知道为什么支持并发高性能,而不是去纠结其有没有单线程管理程序。
  • 打赏
  • 举报
回复
[Quote=引用 31 楼 的回复:]
大哥人家要的是高并发,你这个连并发都没有了,还谈什么GUID?
我这个是王道信我就OK了
[/Quote]

并发程序就不允许使用lock?那么要lock还有什么用呢?

抠字眼而不看逻辑设计,这就很过分了。就跟完全不会并发也没有什么区别。

并发程序也需要lock,关键是用在关键的主要管理片段、而且尽可能短促。
hehe123456789 2012-04-26
  • 打赏
  • 举报
回复
GUID是可以很好的避免并发,但是因为业务的需求订单号要有特定的格式,所以也不适合,而且订单号如果是GUID的话客户记起订单号也不是那么的方便了
winner2050 2012-04-23
  • 打赏
  • 举报
回复
[Quote=引用 22 楼 的回复:]
没错lock是一个很好的解决方案,也就是像你说的把处理代码放在lock中,就是简单查询和插入。我用多线程去请求生成订单的时候也的确不会出现串单的情况,但就是生成订单的效率让我很纠结,一秒钟就20~30个左右,这样在高并发的情况下该怎么解决?
[/Quote]

只lock生成订单号的代码就行了。
orochiheart 2012-04-23
  • 打赏
  • 举报
回复
用GUID,怎么搞都不会重复,如果重复了 比一个人一生被累劈中10次概率还低
吹风的兔子 2012-04-23
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 的回复:]
随机数在高并发的情况下还是会出现重复的,感觉不可取
[/Quote]

——这是一个正确的结论:
我之前写了一个 自动编码函数,我用 微秒+7位随机数 ——结果都出现重复,更气人的是: 随机数 就是靠 微秒生成的!!!


因此,说依靠 随机数,我觉得不可取!
huayy 2012-04-23
  • 打赏
  • 举报
回复
都是牛人,我接分算了。
风吹腚腚凉 2012-04-23
  • 打赏
  • 举报
回复
[Quote=引用 29 楼 的回复:]
引用 22 楼 的回复:
没错lock是一个很好的解决方案,也就是像你说的把处理代码放在lock中,就是简单查询和插入。我用多线程去请求生成订单的时候也的确不会出现串单的情况,但就是生成订单的效率让我很纠结,一秒钟就20~30个左右,这样在高并发的情况下该怎么解决?


只lock生成订单号的代码就行了。
[/Quote]
大哥人家要的是高并发,你这个连并发都没有了,还谈什么GUID?
我这个是王道信我就OK了
风吹腚腚凉 2012-04-23
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 的回复:]
随机数在高并发的情况下还是会出现重复的,感觉不可取
[/Quote]
GUID加上用户名就OK了~或者GUID+用户IP也OK了
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 的回复:]

还是建议 商户信息+日期到毫秒+随机数
你想下 1毫秒你并发再高能有多高
[/Quote]

实际上(特别是服务器端)根本不可能精确到1毫秒,10毫秒都精确不到。因此当我们进行很低数量级的压力测试时,所谓的“1毫秒”内往往会有十几个并发也不算稀奇。
  • 打赏
  • 举报
回复
[Quote=引用楼主 的回复:]
求高并发情况下生成唯一订单号解决方案。。。
[/Quote]

首先你要明确“订单号”的业务原则。假设业务逻辑定义上就是需要“流水号”,那么就算是另外用一个GUID作为所谓主键,业务逻辑上也必须另外再维护一个唯一流水号机制。而如果“无所谓”,那么就使用GUID好了。

假设需要流水号,那么需要一个独立的流水号管理机制。简单来说,应该有一个表专门管理每一种流水号。包括每一种流水号的前缀、后边序号长度、下一次应该分配的编号、最大允许分配的编号(号段约束)。

关系数据库编程时要注意对其进行数据库事务处理,例如任何涉及到它的业务都应该一开始开启DBTransaction时就首先读取这个记录,然后调用“分配下一个流水号”功能,这样就可以从一开始就禁止其它数据库事务幻像读相同记录。

假设不是关系数据库(例如是NoSql数据库),也可以在内存中管理。在程序启动时将每一种流水号读入内存记录集合中,然后相应的业务要注意当涉及到它的业务是首先lock相应的流水号对象,然后调用“分配下一个流水号”功能,再释放lock。这样就可以保证每一个流水号的分配是在多线程管理程序中,同一时间只有一个线程拿到最新流水号。

“分配下一个流水号”这个操作是在独立设计的流水号管理程序对象中进行,而不是由各个业务程序随意生成流水号。对各个业务,隐藏生成流水号的细节,各个业务无需去知道系统是如何生成流水号的,各个业务只知道调用系统的“获取某一流水号的分配对象,对其加锁,调用其分配下以流水号功能,获取流水号”这几个简单功能。
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 的回复:]

GUID,但别用GUID作主键,会导致碎片问题,用自增长字段做主键
[/Quote]
不懂。什么叫“碎片问题”?一个字段值不管取什么,都不会直接影响记录的磁盘位置,何来的“碎片”问题?数据库是按照自己的空闲记录表来选择新记录的位置,跟字段值没有关系。
dongt1 2012-04-21
  • 打赏
  • 举报
回复
  • 打赏
  • 举报
回复
我所说的“每分钟产生500个工单”是因为产生工单的请求是一个个独立的、来自于互联网上的c/s客户端(silverlight应用)的多次请求,包括了整个通讯时间。因此此效率早已知足了。

如果你一定要求本地每秒产生30个订单,我从来没有见过这种业务要求。
  • 打赏
  • 举报
回复
至于你说一秒钟产生30个订单还感觉“纠结”,我建议你把订单号改为guid,看看能不能提高效率?
  • 打赏
  • 举报
回复
[Quote=引用 22 楼 的回复:]
没错lock是一个很好的解决方案,也就是像你说的把处理代码放在lock中,就是简单查询和插入。我用多线程去请求生成订单的时候也的确不会出现串单的情况,但就是生成订单的效率让我很纠结,一秒钟就20~30个左右,这样在高并发的情况下该怎么解决?
[/Quote]

那么你的程序有很严重的问题。

例如我们的服务端系统,假设一分钟要产生500个工单,使用lock来产生流水号一点也不比使用guid要慢(有自动测试程序会将每一个测试用例统计到毫秒级)。
hehe123456789 2012-04-21
  • 打赏
  • 举报
回复
[Quote=引用 21 楼 的回复:]

不是lock就降低性能。

比如你没有别的好办法协调“流水号管理”问题,那么别的什么办法只会让处理更慢,而恰当地把几行代码放到lock管理程序中,简化了代码,你的程序可能会比其它方法更快。

不是一见到lock就轻率地说它慢。
[/Quote]
没错lock是一个很好的解决方案,也就是像你说的把处理代码放在lock中,就是简单查询和插入。我用多线程去请求生成订单的时候也的确不会出现串单的情况,但就是生成订单的效率让我很纠结,一秒钟就20~30个左右,这样在高并发的情况下该怎么解决?
  • 打赏
  • 举报
回复
不是lock就降低性能。

比如你没有别的好办法协调“流水号管理”问题,那么别的什么办法只会让处理更慢,而恰当地把几行代码放到lock管理程序中,简化了代码,你的程序可能会比其它方法更快。

不是一见到lock就轻率地说它慢。
加载更多回复(16)

62,242

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术交流专区
javascript云原生 企业社区
社区管理员
  • ASP.NET
  • .Net开发者社区
  • R小R
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

.NET 社区是一个围绕开源 .NET 的开放、热情、创新、包容的技术社区。社区致力于为广大 .NET 爱好者提供一个良好的知识共享、协同互助的 .NET 技术交流环境。我们尊重不同意见,支持健康理性的辩论和互动,反对歧视和攻击。

希望和大家一起共同营造一个活跃、友好的社区氛围。

试试用AI创作助手写篇文章吧