我必须为我的应用程序的客户提供一个唯一的号码。 这是一个发票编号,因此它必须是唯一的,并且线程安全当然。
过去我创建了一个单例并使用了一个锁定语句:在锁定期间,我将转到数据库并获取一个新数字,然后释放锁定。
有些东西告诉我这也可以在SqlServer中完成,但在SqlServer中我假设我还必须创建某种锁,因为sql代码(存储过程)也可以并行执行,我猜。
所以当我不得不提供一个锁时,它是否会在c#或Sql中有所作为?
答案 0 :(得分:7)
在SQL Server中使用标识列:
-- Set up
create table UniqueNumberGenerator (UN int identity primary key)
-- Generate value
insert into UniqueNumberGenerator default values
select scope_identity()
这比获取桌面上的锁更快,更轻巧。有关详细信息,请参阅here。
如果您担心该表填满了数千行,请不要担心,您可以定期删除表中的所有行,SQL Server仍会记住要生成的下一个值。如果需要,您可以使用dbcc checkident
重置生成的值。
答案 1 :(得分:2)
我所知道的唯一能够可靠地生成唯一数字的解决方案是GUID数据类型。麻烦的是,这太长了,不能轻易用作订单号。
使用数据库从identity
字段获取下一个数字意味着您不必管理锁定,只需执行插入操作,数据库将提供下一个数字。
当然,如果发票没有保存,则该号码已被使用,现在已“丢失”。如果这不打扰你,那么我会使用那种方法。在代码中执行它是一件痛苦的事情,加上在运行应用程序的实例之外会发生什么?你可以得到相同的数字。
答案 2 :(得分:0)
如果您可以处理其糟糕的外观,数据库的时间戳是线程安全的:SELECT @@dbts
(您可以修剪前导零以使其看起来更像是可接受的发票ID)