two*_*ona 12 sql-server stored-procedures t-sql sql-server-2012
我有一个存储过程,它基本上从一个表中选择值并将它们插入到另一个表中,这是一种归档。我想避免多人同时这样做。
当这个程序正在运行时,我不希望其他人能够启动它,但是我不希望序列化,另一个人在我完成后运行该程序。
我想要的是其他人在我运行该程序时尝试启动它以获取错误。
我尝试过使用 sp_getapplock,但是我无法完全阻止该人运行该程序。
我还尝试使用 sys.dm_exec_requests 查找过程并阻止该过程,虽然这确实有效,但我认为这不是最佳选择,因为在某些服务器上我没有运行 sys.dm_exec_sql_text(sql_handle) 的权限。
我这样做的最佳方法是什么?
Dav*_*oft 15
要添加到@Tibor-Karaszi 的答案中,设置锁定超时实际上不会产生错误(我已针对文档提交了 PR)。sp_getapplock 只返回 -1,因此您必须检查返回值。所以像这样:
create or alter procedure there_can_be_only_one
as
begin
begin transaction
declare @rv int
exec @rv = sp_getapplock 'only_one','exclusive','Transaction',0
if @rv < 0
begin
throw 50001, 'There is already an instance of this procedure running.', 10
end
--do stuff
waitfor delay '00:00:20'
commit transaction
end
Run Code Online (Sandbox Code Playgroud)
另一种选择是建立一个表来控制对程序的访问。下面的示例显示了一个可能的表以及可以使用它的过程。
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
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
6250 次 |
最近记录: |