防止存储过程同时执行两次

时间:2009-07-29 21:05:20

标签: sql-server stored-procedures sql-server-2000

我有一个SQL Server 2000的存储过程,它只能在任何给定时刻执行单个实例。有没有办法检查并确保程序当前没有执行?

理想情况下,我希望代码能够自包含且高效(快速)。我也不想做一些像创建全局临时表来检查它是否存在的事情,因为如果程序由于某种原因失败,它将始终被视为正在运行......

我搜索过,我认为还没有被问过。如果是的话,抱歉。

5 个答案:

答案 0 :(得分:10)

是的,有一种方法。使用所谓的SQL Server Application locks

编辑:是的,这也适用于SQL Server 2000

答案 1 :(得分:5)

您可以使用锁定sp_getapplock的示例中的sp_releaseapplock Stored Procedure for Single Use Only

但是,你真正想做的是什么?您是否尝试使用high isolation level进行交易?在应用程序级别处理这种类型的并发性可能会好得多,因为通常更高级别的语言对于那种事情具有更好的原语。

答案 2 :(得分:1)

如何锁定虚拟表?如果发生故障,这不会导致死锁。

答案 3 :(得分:0)

在程序开始时检查数据是否被“锁定”(如果没有锁定)

程序结束时解锁数据。

SELECT @IsLocked=IsLocked FROM CheckLockedTable Where spName = 'this_storedProcedure'

IF @IsLocked = 1
    RETURN
ELSE
    UPDATE CheckLockedTable SET IsLocked = 1 Where spName = 'this_storedProcedure'

.
.
.

-- At end of Stored Procedure
    UPDATE CheckLockedTable SET IsLocked = 0 Where spName = 'this_storedProcedure'

答案 4 :(得分:0)

在回复中共享的初始外部链接之一提供了有用的信息,但是我个人更希望将独立答案/摘录放在“堆栈溢出”问题页面上。有关我使用和解决(类似)问题的内容,请参见下面的代码段。如果有人遇到问题(或调整建议),请发出提示。

IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[MyLockedAndDelayedStoredProcedure]') AND type in (N'P', N'PC'))
DROP PROCEDURE [GetSessionParticipantAnswersFromEmailAddressAndSessionName]
GO

CREATE PROCEDURE [MyLockedAndDelayedStoredProcedure]    
  @param1 nvarchar(max) = ''
AS
BEGIN

DECLARE @LockedTransactionReturnCode INT
PRINT 'MyLockedAndDelayedStoredProcedure CALLED at ' + CONVERT(VARCHAR(12),GETDATE(),114);
BEGIN TRANSACTION
EXEC @LockedTransactionReturnCode =sp_getapplock @Resource='MyLockedAndDelayedStoredProcedure_LOCK', @LockMode='Exclusive', @LockOwner='Transaction', @LockTimeout = 10000
PRINT 'MyLockedAndDelayedStoredProcedure STARTED at ' + CONVERT(VARCHAR(12),GETDATE(),114);

-- Do your Stored Procedure Stuff here
Select @param1;

-- If you don't want/need a delay remove this line    
WAITFOR DELAY '00:00:3'; -- 3 second delay
PRINT 'MyLockedAndDelayedStoredProcedure ENDED at ' + CONVERT(VARCHAR(12),GETDATE(),114);
COMMIT

END

-- https://gist.github.com/cemerson/366358cafc60bc1676f8345fe3626a3f