【发布时间】:2019-11-25 00:37:03
【问题描述】:
我需要在 C# 中生成类似于 lock 的语句,这是一个可以包含多个操作的同步范围。假设我有一个表GeneratedKeys 来跟踪数据库为其他一些表生成的所有会话密钥。它有一个主键列[Key]和一个用户自定义函数dbo.GenerateKey(),可以生成下一个随机键。我只想插入唯一的键,所以我必须验证生成的键的唯一性,因此我必须重新生成它,直到它变得唯一。这需要一个同步块,因为这里发生了几个操作。我的做法:
WHILE (1 = 1)
BEGIN
DECLARE @newKey CHAR(10) = dbo.GenerateKey();
DECLARE @existingKey CHAR(10) = NULL;
SELECT TOP 1 @existingKey = [entry].[Key]
FROM [dbo].[GeneratedKeys] [entry] WITH (TABLOCKX, HOLDLOCK)
WHERE [entry].[Key] = @newKey
-- go to re-generate if matched
IF @existingKey IS NOT NULL
CONTINUE;
-- insert only a unique key
INSERT INTO [dbo].[GeneratedKeys]([Key], [CreatedOnUtc])
OUTPUT [INSERTED].[Key] [Key]
SELECT @newKey, GETUTCDATE()
BREAK;
END
我的问题是 - 我是否选择了正确的锁定提示组合?首先,获取整个表的TABLOCKX 排他锁,并将其扩展到HOLDLOCK 剩余块的末尾。
【问题讨论】:
标签: c# sql .net sql-server