2012-11-27 54 views
2

我有一个需要生成一个序列号作为主键(在旧系统)生成一个序列号

我想知道,如果以下解决方案中的竞争条件从并发遭受。

CREATE TABLE SequenceGenerator 
(
    Sequence INT 
) 

INSERT INTO SequenceGenerator SELECT 0 

这里是每当我需要一个序列号

CREATE PROCEDURE GetNextSequence 
AS 
    SET NOCOUNT ON 
    DECLARE @NextSequence INT 
    UPDATE SequenceGenerator SET 
    @NextSequence = Sequence, 
    Sequence = Sequence + 1 
    RETURN @NextSequence + 1 

感谢

+2

什么版本的SQL Server? 2012有序列,以前的版本有'IDENTITY'列。如果你解释为什么你想为自己的代码编写代码会有帮助吗? – Pondlife

+0

[在Sql Server中创建序列]的可能重复(http://stackoverflow.com/questions/1834733/creating-sequence-in-sql-server) –

+0

以下是2012年的操作方法:http://stackoverflow.com/a/39774566/3347858 –

回答

2

是的,我会被调用存储过程。

是否有某些原因导致您无法识别字段(即:identity(1,1))?

如果你想使用上面的代码,你应该把它包装在一个可序列化的事务中,并处理任何死锁情况。

+0

但是我的问题是关于“是否UPDATE语句是原子的?..如果是这样..那么它默认情况下是隐式事务。如果这是真的..那么为什么包装在事务中?它可以陷入僵局吗?“ 对不起。如果我原来的问题不清楚。 谢谢 – kudlur

2

为什么你不使用身份列?

IDENTITY [ (seed ,increment) ] 

IDENTITY (Property)

EG。

CREATE TABLE SequenceGenerator 
(
    Sequence INT IDENTITY(1,1) 
) 
0

这不是很漂亮,但我已经在SQL Server 2008 R2以下工作好几年了,它从来没有让我失望:

我有一个表有“名”和“LastValue “列:

CREATE PROCEDURE [dbo].[ReserveSequence] 
@Name varchar(100), 
@Count int, 
@FirstValue bigint OUTPUT 
AS 
BEGIN 
SET NOCOUNT ON; 

DECLARE @Results TABLE ([LastValue] bigint) 

UPDATE [Sequences] 
SET [LastValue] = [LastValue] + @Count 
OUTPUT INSERTED.LastValue INTO @Results 
WHERE [Name] = @Name; 

SELECT TOP 1 @FirstValue = [LastValue] + 1 FROM @Results; 
RETURN 0; 
END 

这就是说,我会使用,如果你靶向2012或更高版本的序列对象。

0

这将做到这一点,你不会遇到并发问题。

CREATE TABLE SequenceGenerator(Sequence INT) 
GO 
INSERT INTO SequenceGenerator SELECT 0 
GO 

DECLARE @NextSequence INT 

UPDATE SequenceGenerator 
SET @NextSequence = Sequence = Sequence + 1 

@NextSequence将递增值