Sql server 查明存储过程是否已在运行

Sql server 查明存储过程是否已在运行,sql-server,sql-server-2012,Sql Server,Sql Server 2012,这是我在SQL Server 2012中运行的存储过程 ALTER PROCEDURE usp_ProcessCustomers AS BEGIN IF EXISTS (SELECT 1 FROM RunningProcesses WHERE ProcessId = 1 AND IsRunning = 1) RETURN; UPDATE RunningProcesses SET IsRunning = 1 WHERE ProcessId = 1

这是我在SQL Server 2012中运行的存储过程

ALTER PROCEDURE usp_ProcessCustomers
AS
BEGIN
    IF EXISTS (SELECT 1 FROM RunningProcesses WHERE ProcessId = 1 AND IsRunning = 1)
       RETURN;

    UPDATE RunningProcesses 
    SET IsRunning = 1 
    WHERE ProcessId = 1

-- Do processing here
-- Do processing here

UPDATE RunningProcesses 
    SET IsRunning = 0 
    WHERE ProcessId = 1
END
GO
此存储过程可以从应用程序中的多个位置触发。如果需要,甚至DBA也可以使用SSM触发存储过程

到目前为止还不错

问题是,如果出现问题,或者DBA取消了存储过程的执行,则
runningprocesss
中的
IsRunning
值永远不会更新回0。因此,系统总是认为存储过程正在运行,即使它没有运行

我在web上找到了以下脚本,用于检查脚本是否正在运行

SELECT 
    r.*, t.text 
FROM 
    sys.dm_exec_requests r 
CROSS APPLY
    sys.dm_exec_sql_text(r.sql_handle) t
WHERE 
    r.status IN (N'Suspended', N'Running', N'Runnable', N'Pending')
使用上面的脚本来确定存储过程是否已经在运行,这是一种好方法吗?如果它已经在运行,那么我将使用
RETURN
关键字退出存储过程。如果这不是一个好主意,那么解决此问题的最佳方法是什么。

使用内置的。SQL Server确保在会话或服务器意外关闭时释放锁

ALTER PROCEDURE usp_ProcessCustomers
AS
BEGIN
    BEGIN TRANSACTION

    declare @Lock int
    EXEC @Lock = sp_getapplock @Resource = 'ProcessCustomers',
                               @LockMode = 'Exclusive'
    IF (@Lock < 0)  -- already locked by another process
       RETURN;

-- Do processing here
-- Do processing here

    EXEC sp_releaseapplock @Resource = 'ProcessCustomers'

    COMMIT TRANSACTION
END
ALTER程序usp\u流程客户
作为
开始
开始交易
声明@Lock int
EXEC@Lock=sp_getapplock@Resource='ProcessCustomers',
@锁定模式='独占'
IF(@Lock<0)--已被另一个进程锁定
返回;
--在这里处理吗
--在这里处理吗
EXEC sp_releaseapplock@Resource='ProcessCustomers'
提交事务
结束

似乎是个好主意,但我发现“您试图在没有活动事务的情况下获取事务应用程序锁”错误。我不打算在存储过程中使用任何事务,因为不需要任何事务。我的错误是,使用应用程序锁需要事务,并且我已经修复了包含BEGIN/COMMIT事务语句的代码。然而,在这里使用事务应该没有任何负面影响。