根据特定条件生成唯一的连续序列号,而不使用TABLOCKX

时间:2016-07-08 15:02:56

标签: sql-server locking sequence isolation-level database-concurrency

在名为'确认'的表格中插入新条目。每次向我的客户发送消息时。在插入过程中,我需要获得' SequenceNumber'的最大值。白天向我的特定客户发送的确认栏。然后将此SequenceNumber递增1并用于新记录。

约束是确保为白天发送给同一客户的确认生成连续的唯一序列号。

我已经能够使用Serializable隔离级别和TABLOCKX提示来实现它。此解决方案有效,但在并发性方面无法提供最佳性能。知道如何实现这个解决方案以提供更好的性能吗?

当前解决方案(封装在存储过程中)

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
BEGIN TRAN

SELECT @SequenceNumber = MAX (SequenceNumber)                           
        FROM dbo.Confirmation WITH (TABLOCKX)
        WHERE   DATEDIFF(dd, CreationDate, @creationDate) = 0 AND
                ClientId = @recipientId

IF (@SequenceNumber IS NULL)
    SET @SequenceNumber = 1
ELSE
    SET @SequenceNumber = @SequenceNumber+1

INSERT INTO Confirmation (...) VALUES (..., @SequenceNumber, ...)

COMMIT TRAN

1 个答案:

答案 0 :(得分:0)

serializable您不需要任何提示。引擎为您提供as-if-serial执行。在这里,这相当于锁定SequenceNumber希望存在的索引中的最后一行。这基本上可以工作但你需要死锁重试。

我用这个:

SELECT @SequenceNumber = MAX (SequenceNumber)                           
FROM dbo.Confirmation WITH (UPDLOCK, HOLDLOCK, ROWLOCK)
WHERE ...

为此,您不需要任何特定的隔离级别,因为HOLDLOCK强制序列化。这几乎总是无死锁(几乎因为引擎没有正式保证)。