You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让SQL Server 2019模拟存储过程执行中,避免并发调用冲突?

解决存储过程并发执行导致的数据异常问题

这个场景我太熟了——批量刷新报表表的存储过程最怕并发调用,截断+插入的组合在并发下肯定出乱子。要实现“后续调用自动等待前一个完成,且最终都能拿到最新数据”的效果,用SQL Server的**应用程序锁(Application Lock)**是最直接的方案,完全满足你的需求。

具体实现思路

我们要给RefreshTemps存储过程加一个全局的排他锁:当第一个会话(用户A)执行时,先获取这个锁,执行完刷新逻辑后释放锁;后续会话(用户B)调用时,会自动等待锁释放,直到前一个执行完成才会开始自己的刷新流程。这样就不会出现同时截断、插入的冲突,所有调用最终都会拿到一致的最新数据。

修改后的存储过程代码

ALTER PROCEDURE Reporting.dbo.RefreshTemps
AS
BEGIN
    SET NOCOUNT ON;

    DECLARE @LockResult INT;

    -- 获取应用程序排他锁,锁名称要唯一,这里用存储过程名确保不会和其他锁冲突
    -- 超时时间设为-1表示无限等待(直到锁被释放)
    EXEC @LockResult = sp_getapplock
        @Resource = 'RefreshTemps_Lock',
        @LockMode = 'Exclusive',
        @LockOwner = 'Session',
        @LockTimeout = -1;

    -- 检查是否成功获取锁(正常情况下会等待到获取为止,这里做个防御性检查)
    IF @LockResult < 0
    BEGIN
        RAISERROR('无法获取刷新锁,请稍后重试', 16, 1);
        RETURN;
    END

    BEGIN TRY
        -- 你的原有刷新逻辑:截断表+INSERT INTO
        TRUNCATE TABLE Reporting.dbo.TempTable1;
        INSERT INTO Reporting.dbo.TempTable1
        SELECT * FROM Production.dbo.SourceTable1;

        TRUNCATE TABLE Reporting.dbo.TempTable2;
        INSERT INTO Reporting.dbo.TempTable2
        SELECT * FROM Production.dbo.SourceTable2;

        -- 其他表的刷新逻辑...

    END TRY
    BEGIN CATCH
        -- 捕获异常,抛出错误
        THROW;
    END CATCH
    FINALLY
        -- 无论成功还是失败,都要释放锁,避免锁一直占用
        EXEC sp_releaseapplock
            @Resource = 'RefreshTemps_Lock',
            @LockOwner = 'Session';
    END
END

关键细节解释

  • 锁的唯一性:@Resource参数用了RefreshTemps_Lock,确保只有这个存储过程会使用这个锁,不会和其他业务逻辑的锁冲突。
  • 排他锁模式:@LockMode = 'Exclusive'意味着同一时间只有一个会话能持有这个锁,后续调用必须等待。
  • 无限等待:@LockTimeout = -1表示后续调用会一直等待直到锁释放,符合你“不执行B的调用,而是等待A完成”的需求(用户看到的就是存储过程在“运行中”,实际在排队)。
  • 锁的释放:用FINALLY块确保无论存储过程成功还是出错,锁都会被释放,避免出现死锁或者锁一直占用的情况。

这样修改后,不管有多少人或程序调用EXEC Reporting.dbo.RefreshTemps,都会按顺序排队执行,完全解决并发刷新导致的数据异常问题,所有调用最终都会拿到更新后的一致数据。

内容的提问来源于stack exchange,提问作者Geoff Griswald

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 07:43:06