2

每次向我的客户发送消息时,都会在名为“确认”的表中插入一个新条目。在插入过程中,我需要获取白天发送给我的特定客户的确认的“SequenceNumber”列的 MAX 值。然后此 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
4

1 回答 1

0

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

我会用这个:

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

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

于 2016-07-08T16:18:36.213 回答