高并发,保证订单号唯一

lmc19860810 2013-07-17 06:03:17
这是我在网上看来的。求大家验证

CREATE TABLE [dbo].[SerialNo](
[sCode] [varchar](50) NOT NULL,--主键也是多个流水号的类别区分
[sName] [varchar](100) NULL,--名称,备注形式
[sQZ] [varchar](50) NULL,--前缀
[sValue] [varchar](80) NULL,--因子字段
CONSTRAINT [PK_SerialNo] PRIMARY KEY CLUSTERED
(
[sCode] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON,

ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]


==========================================================================

Create procedure [dbo].[GetSerialNo]
(
@sCode varchar(50)
)

as

--exec GetSerialNo

begin

Declare @sValue varchar(16),

@dToday datetime,

@sQZ varchar(50) --这个代表前缀

Begin Tran

Begin Try

-- 锁定该条记录,好多人用lock去锁,起始这里只要执行一句update就可以了
--在同一个事物中,执行了update语句之后就会启动锁
Update SerialNo set sValue=sValue where sCode=@sCode

Select @sValue = sValue From SerialNo where sCode=@sCode

Select @sQZ = sQZ From SerialNo where sCode=@sCode

-- 因子表中没有记录,插入初始值

If @sValue is null

Begin

Select @sValue = convert(bigint, convert(varchar(6), getdate(), 12) + '000001')

Update SerialNo set sValue=@sValue where sCode=@sCode

end else

Begin --因子表中没有记录

Select @dToday = substring(@sValue,1,6)

--如果日期相等,则加1

If @dToday = convert(varchar(6), getdate(), 12)

Select @sValue = convert(varchar(16), (convert(bigint, @sValue) + 1))

else --如果日期不相等,则先赋值日期,流水号从1开始

Select @sValue = convert(bigint, convert(varchar(6), getdate(), 12) +'000001')



Update SerialNo set sValue =@sValue where sCode=@sCode

End

Select result = @sQZ+@sValue

Commit Tran

End Try

Begin Catch

Rollback Tran

Select result = 'Error'

End Catch

end
...全文
614 9 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
why7282299 2013-11-21
  • 打赏
  • 举报
回复
1、与其你这样写哪里弄来的存储过程,那你还不如用数据库自增长的方式,这样确定唯一,肯定比你这个要快,然后再在程序里组织成你想要的唯一订单号。 2、用楼上大家们说的guid,可以生成唯一,其实也未必快。 3、自己写代码用好锁的机制生产,这样子能达到最高的效率。 4、既然是并发并发并发,不管如何一个实现就算到CPU级别的实现,都是存在锁的,排他性得要有,就看你写的哪种方式最快了,看你用的语言,有没有合适的底层及接口提供。
  • 打赏
  • 举报
回复
lz看来是抄袭的代码存储过程代码,因为连“流水号”跟“唯一号”的区别都没有能说清楚。 这个问题,目的是要保证所有确定提交的号码都是流水号(即使在多用户操作有些人会撤销操作情况下),而不仅仅是什么简单的“唯一号”。
chai1338 2013-07-27
  • 打赏
  • 举报
回复
流水ID 000000000000000000000001开始都可以
饕餮123 2013-07-27
  • 打赏
  • 举报
回复
引用 5 楼 banian_cn 的回复:
有时候用Guid并不方便的,我的订单号也是自动生成的,每天从1开始计算。这样比较好记。比如13072600001 日期就不需要在存储过程中算了,写一个取号的存储过程就可以了,实际是对表插入一条数据, 直接取自增主键即可。第一单就是1,规则可以再取号后自己拼接。 至于并发,不会出现同时插入两条一样主键的数据的。
唯一主键会降低性能的
Banianer 2013-07-26
  • 打赏
  • 举报
回复
有时候用Guid并不方便的,我的订单号也是自动生成的,每天从1开始计算。这样比较好记。比如13072600001 日期就不需要在存储过程中算了,写一个取号的存储过程就可以了,实际是对表插入一条数据, 直接取自增主键即可。第一单就是1,规则可以再取号后自己拼接。 至于并发,不会出现同时插入两条一样主键的数据的。
njrc 2013-07-26
  • 打赏
  • 举报
回复
学习下,估计楼主是要自己编辑这个订单号(有编号规则),同问求解,以前单位有一报名系统,生成报名号,用php写的,老是出现重号考生
ltcszk 2013-07-18
  • 打赏
  • 举报
回复
用guid不比你这个方便?而且程序里就能生成不需要DB
by_封爱 2013-07-17
  • 打赏
  • 举报
回复
guid identity(1,1) 想验证 自己开100个线程测试就好了 你光看 是看不出来东西的...
  • 打赏
  • 举报
回复
Guid

62,243

社区成员

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

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

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

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