【问题标题】:Can a heavy Stored Procedure wait another SP to finish?繁重的存储过程可以等待另一个 SP 完成吗?
【发布时间】:2014-12-11 18:10:56
【问题描述】:

我有一个将信息插入 SQL 数据库的应用程序。然后它必须运行一个繁重的存储过程。问题是当我对该 SP 的调用超过 2 或 3 次时,它开始抛出错误。

我为避免这个问题所做的就是在表格中添加一个标志,例如:

IF NOT EXISTS(SELECT TOP 1 File_Key FROM File WHERE Flag_Value = 3)
    BEGIN
    WHILE EXISTS(SELECT TOP 1 File_Key FROM File WHERE Flag_Value = 1)
        BEGIN

        DECLARE @LocalFile_Key int = (SELECT TOP 1 File_Key FROM File WHERE Flag_Value = 1)

        UPDATE File
        SET Flag_Value = 3
        WHERE File_Key = @LocalFile_Key

        File Process...

        Update File
        Set Flag_Value = 2
        Where File_Key = @LocalFile_Key
    END
END

但我仍然可以看到有时 2 个存储过程会运行,这很奇怪。当存储出现问题时,它会留下 Flag_Value '3',因此它会锁定存储过程。

【问题讨论】:

  • 您应该将 SP 包装在具有适当隔离级别的事务中。

标签: mysql sql tsql stored-procedures


【解决方案1】:

您遇到了并发问题。您可以通过应用锁来锁定并发过程的执行。在程序开始时由sp_getapplock 锁定,在程序结束时由sp_releaseapplock 释放锁,当程序调用它时,另一个并发调用的程序应该等到被调用的程序第一次释放锁。

在程序的开头添加这个块。

DECLARE @result int;
EXEC @result = sp_getapplock @Resource = 'ProccessFileProc', @LockMode = 'Exclusive';
IF @result < 0
BEGIN
    ROLLBACK TRANSACTION;
END

通过这个解决方案并发调用 sp 等待另一个 sp 完成。

【讨论】:

  • 所以代码会停在 Exec @result 这一行,等到锁被释放??
  • sp1 被调用,所以它拥有锁,然后当 sp2 到达获得锁时调用它应该等到 sp1 释放锁。
  • 这个答案对 Bernardo Isidro Guerrero 有用吗?
猜你喜欢
  • 2011-01-30
  • 1970-01-01
  • 2021-10-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多