我正在编写一个 T-SQL 存储过程,仅当相似记录的数量低于某个阈值(在下面的示例中为 10)时,该过程才会有条件地将记录添加到表中。问题是这将从 Web 应用程序运行,因此它将在多个线程上运行,并且我需要确保该表永远不会有超过 10 条相似记录。
该过程的基本要点是:
BEGIN
DECLARE @c INT
SELECT @c = count(*)
FROM foo
WHERE bar = @a_param
IF @c < 10 THEN
INSERT INTO foo
(bar)
VALUES (@a_param)
END IF
END
我认为我可以通过将 select 语句替换为以下内容来解决任何潜在的并发问题:
SELECT @c = count(*) WITH (TABLOCKX, HOLDLOCK)
但是我很好奇除了锁提示之外是否还有其他方法可以管理 T-SQL 中的并发问题
请您参考如下方法:
一种选择是使用 sp_getapplock系统存储过程。您可以将关键部分逻辑放在事务中,并使用 sql server 内置的锁定来确保同步访问。
示例:
CREATE PROC MyCriticalWork(@MyParam INT)
AS
DECLARE @LockRequestResult INT
SET @LockRequestResult=0
DECLARE @MyTimeoutMiliseconds INT
SET @MyTimeoutMiliseconds=5000--Wait only five seconds max then timeouit
BEGIN TRAN
EXEC @LockRequestResult=SP_GETAPPLOCK 'MyCriticalWork','Exclusive','Transaction',@MyTimeoutMiliseconds
IF(@LockRequestResult>=0)BEGIN
/*
DO YOUR CRITICAL READS AND WRITES HERE
*/
--Release the lock
COMMIT TRAN
END ELSE
ROLLBACK TRAN