Sql-Server

使用 SET LOCK_TIMEOUT 執行儲存過程

  • January 22, 2018

反正有沒有SET LOCK_TIMEOUT明確地執行儲存過程?

例如,我呼叫了 sproc dbo.LoadData。它只是從表中獲取數據dbo.Abc並將它們插入到表中dbo.Xyz

現在我想執行 sproc dbo.LoadData,但如果表超過 10 秒,則停止執行儲存過程dbo.Abclocked

我知道該選項SET LOCK_TIMEOUT可以在儲存dbo.LoadData過程本身中實現,但我想知道是否有任何方法可以顯式呼叫它(=不在儲存過程本身中實現該選項)。

LOCK_TIMEOUT不僅是會話級別的設置,還需要單獨批量設置。但是,它不能通過變數設置。因此,這可以通過在“主”儲存過程中使用動態 SQL 來完成。這將允許設置LOCK_TIMEOUT然後執行應在此特定設置中執行的任何其他儲存過程。它必須是動態 SQL 的單次執行,因為設置將恢復為最頂層/最外層程序的值。例如:

在 SSMS 的一個查詢選項卡中執行它:

GO
CREATE PROCEDURE ##ShouldTimeout
AS
INSERT INTO ##LockedTable ([ID]) VALUES (1);
GO


GO
CREATE PROCEDURE ##TimeoutTest
(
   @SecondsUntilTimeout INT = 2
)
AS
SET NOCOUNT ON;

SET @SecondsUntilTimeout = ISNULL(@SecondsUntilTimeout, 2); -- enforce default

DECLARE @SQL NVARCHAR(MAX) = N'SET LOCK_TIMEOUT ';
SET @SQL += CONVERT(NVARCHAR(MAX), @SecondsUntilTimeout * 1000) + N';
';

SET @SQL += N'EXEC ##ShouldTimeout;'; -- use CASE / IF to decide what to exec

RAISERROR(@SQL, 10, 1) WITH NOWAIT; -- print Dynamic SQL in "Messages" tab

EXEC (@SQL);
GO

在 SSMS 的另一個查詢選項卡中執行以下命令:

BEGIN TRAN;
CREATE TABLE ##LockedTable (ID INT);

-- ROLLBACK

現在回到第一個查詢選項卡(您在其中創建了兩個臨時儲存過程)並執行以下兩個測試:

EXEC ##TimeoutTest;
-- this will timeout after 2 seconds (the default)


EXEC ##TimeoutTest 5;
-- this will timeout after 5 seconds

現在返回到第二個查詢選項卡並執行ROLLBACK;-)。

不,你不能那樣做。這是您的連接的屬性。

線上書籍:

在連接開始時,此設置的值為 -1。更改後,新設置在連接的其餘部分保持有效。SET LOCK_TIMEOUT 的設置是在執行或執行時設置的,而不是在解析時設置的。

關於如何使用它的幾個例子和討論:

  1. SET LOCK_TIMEOUT,是基於會話還是基於語句?
  2. https://blog.sqlauthority.com/2013/01/28/sql-server-basic-explanation-of-set-lock_timeout-how-to-not-wait-on-locked-query/
  3. 我們可以設置 LOCK_TIMEOUT 實例範圍或數據庫範圍嗎?

引用自:https://dba.stackexchange.com/questions/179443