另一种选择是建立一个表来控制对该过程的访问。下面的示例显示了可能的表格以及可以使用该表格的过程。
CREATE TABLE dbo.ProcedureLock
(
ProcedureLockID INT NOT NULL IDENTITY(1,1)
, ProcedureName SYSNAME NOT NULL
, IsLocked BIT NOT NULL CONSTRAINT DF_ProcedureLock_IsLocked DEFAULT (0)
, UserSPID INT NULL
, DateLockTaken DATETIME2(7) NULL
, DateLockExpires DATETIME2(7) NULL
, CONSTRAINT PK_ProcedureLock PRIMARY KEY CLUSTERED (ProcedureLockID)
)
CREATE UNIQUE NONCLUSTERED INDEX IDXUQ_ProcedureLock_ProcedureName
ON dbo.ProcedureLock (ProcedureName)
INSERT INTO dbo.ProcedureLock
(ProcedureName, IsLocked)
VALUES ('dbo.DoSomeWork', 0)
GO
CREATE PROCEDURE dbo.DoSomeWork
AS
BEGIN
/** Take Lock */
UPDATE dbo.ProcedureLock
SET IsLocked = 1
, UserSPID = @@SPID
, DateLockTaken = SYSDATETIME()
, DateLockExpires = DATEADD(MINUTE, 10, SYSDATETIME())
WHERE ProcedureName = 'dbo.DoSomeWork'
AND (IsLocked = 0
OR (IsLocked = 1 AND DateLockExpires < SYSDATETIME())
)
IF COALESCE(@@ROWCOUNT, 0) = 0
BEGIN
;THROW 50000, 'This procedure can only be run one at a time, please wait', 1;
END
/** DO WHATEVER NEEDS TO BE DONE */
/** Release the lock */
UPDATE dbo.ProcedureLock
SET IsLocked = 0
, UserSPID = NULL
, DateLockTaken = NULL
, DateLockExpires = NULL
WHERE ProcedureName = 'dbo.DoSomeWork'
END