我有一个存储过程,基本上从一个表插入到另一个表。
虽然此过程正在运行,但我不希望其他任何人都可以启动它,但是我不希望序列化,因此在完成后,其他人可以运行该过程。
我想要的是在我运行该过程时试图启动它的其他人的错误。
我尝试使用sp_getapplock,但是我无法完全阻止该人运行该过程。
我还尝试使用sys.dm_exec_requests查找该过程并阻止该过程,尽管这确实可行,但我认为它不是最佳的,因为在某些服务器上我没有运行sys.dm_exec_sql_text(sql_handle)的权限。
我这样做的最佳方法是什么?
答案 0 :(得分:0)
狡猾的特技:
ALTER PROC MyProc
AS
BEGIN TRY
IF OBJECT_ID('tembdb..##lock_proc_MyProc') IS NOT NULL
RAISERROR('Not now.', 16, 0)
ELSE
EXEC('CREATE TABLE ##lock_proc_MyProc (dummy int)')
...
EXEC('DROP TABLE ##lock_proc_MyProc')
END TRY
BEGIN CATCH
...
EXEC('DROP TABLE ##lock_proc_MyProc')
...
END CATCH
GO
可以通过存储spid并监视僵尸##来扩展。
您还可以提高隔离级别/粒度,例如TABLOCK
,UPDLOCK
:
ALTER PROC MyProc
AS
BEGIN TRAN
DECLARE @dummy INT
SELECT @dummy=1
FROM t (TABLOCKX, HOLDLOCK)
WHERE 1=0
...
COMMIT TRAN
这将产生不同的效果-将等待而不是掉下去。