我正在编写一个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