我有一个SQL Server 2000的存储过程,它只能在任何给定时刻执行单个实例。有没有办法检查并确保程序当前没有执行?
理想情况下,我希望代码能够自包含且高效(快速)。我也不想做一些像创建全局临时表来检查它是否存在的事情,因为如果程序由于某种原因失败,它将始终被视为正在运行......
我搜索过,我认为还没有被问过。如果是的话,抱歉。
答案 0 :(得分:10)
编辑:是的,这也适用于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