SQL 服务器 Table 锁定
SQL Server Table Locking
我需要为客户创建一个唯一标识符,我正在使用 9 位数字 Luhn(第 9 位数字是校验位)来实现它,因此我可以验证其真实性。我想要生成的数字是随机的,所以我创建了一个 8 位数字并计算出与之匹配的校验位,这太棒了。
我的问题是我需要检查它是否不存在于我的客户端 table。我添加了一个索引以确保无法插入重复值,但我正在寻找有关如何锁定我创建的事务中涉及的 table 以确保不会出现并发问题的指导,即不能尝试插入副本。
欢迎提出任何关于方法或建议的建议,我知道这可能是一个无聊的问题。
简短的回答是您无法直接控制使用哪种类型的锁以及何时使用。但是,您确实有能力在明确定义的事务中放置多个语句。
在交易结束时,您可以检查处理是否有错误,或者您的数据是否处于无效状态。然后,如果一切正常,您将提交;否则,您将回滚。但是,请注意不要让交易保持开放状态!如果您不提交或回滚事务,受影响的表将保持锁定状态,并且针对这些表的所有事务都将被阻止,直到您提交或回滚事务。
下面是一个示例,希望对您有所帮助:
DECLARE @Table TABLE
(
ID INT IDENTITY PRIMARY KEY
,Luhn INT
,UNIQUE(Luhn)
)
DECLARE @MaxTries INT = 10;
DECLARE @Try INT = 1;
DECLARE @Luhn INT;
DECLARE @IsLuhnAvailable BIT = 0;
BEGIN TRAN;
WHILE @IsLuhnAvailable = 0 AND @Try <= @MaxTries
BEGIN
SET @Luhn = CHECKSUM(NEWID()); --dbo.GenerateLuhn()
SET @IsLuhnAvailable = CASE WHEN EXISTS ( SELECT 1 FROM @Table WHERE Luhn = @Luhn ) THEN 0 ELSE 1 END;
SET @Try +=1;
END
IF @IsLuhnAvailable = 0
BEGIN
PRINT 'Luhn could not be generated.'
ROLLBACK;
END
ELSE
BEGIN
INSERT INTO @Table
(
Luhn
)
VALUES
(
@Luhn
)
PRINT 'New Luhn was generated: ' + CAST(@Luhn AS VARCHAR)
COMMIT;
END
SELECT * FROM @Table
我需要为客户创建一个唯一标识符,我正在使用 9 位数字 Luhn(第 9 位数字是校验位)来实现它,因此我可以验证其真实性。我想要生成的数字是随机的,所以我创建了一个 8 位数字并计算出与之匹配的校验位,这太棒了。
我的问题是我需要检查它是否不存在于我的客户端 table。我添加了一个索引以确保无法插入重复值,但我正在寻找有关如何锁定我创建的事务中涉及的 table 以确保不会出现并发问题的指导,即不能尝试插入副本。
欢迎提出任何关于方法或建议的建议,我知道这可能是一个无聊的问题。
简短的回答是您无法直接控制使用哪种类型的锁以及何时使用。但是,您确实有能力在明确定义的事务中放置多个语句。
在交易结束时,您可以检查处理是否有错误,或者您的数据是否处于无效状态。然后,如果一切正常,您将提交;否则,您将回滚。但是,请注意不要让交易保持开放状态!如果您不提交或回滚事务,受影响的表将保持锁定状态,并且针对这些表的所有事务都将被阻止,直到您提交或回滚事务。
下面是一个示例,希望对您有所帮助:
DECLARE @Table TABLE
(
ID INT IDENTITY PRIMARY KEY
,Luhn INT
,UNIQUE(Luhn)
)
DECLARE @MaxTries INT = 10;
DECLARE @Try INT = 1;
DECLARE @Luhn INT;
DECLARE @IsLuhnAvailable BIT = 0;
BEGIN TRAN;
WHILE @IsLuhnAvailable = 0 AND @Try <= @MaxTries
BEGIN
SET @Luhn = CHECKSUM(NEWID()); --dbo.GenerateLuhn()
SET @IsLuhnAvailable = CASE WHEN EXISTS ( SELECT 1 FROM @Table WHERE Luhn = @Luhn ) THEN 0 ELSE 1 END;
SET @Try +=1;
END
IF @IsLuhnAvailable = 0
BEGIN
PRINT 'Luhn could not be generated.'
ROLLBACK;
END
ELSE
BEGIN
INSERT INTO @Table
(
Luhn
)
VALUES
(
@Luhn
)
PRINT 'New Luhn was generated: ' + CAST(@Luhn AS VARCHAR)
COMMIT;
END
SELECT * FROM @Table