sql – 根据计数在多线程环境中有条件地将记录插入表中

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