Skip to main content
 首页 » 编程设计

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

2024年02月23日10tintown

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