Sql-Server

如何確定哪個語句阻止 SQL Server 中的更新

  • August 9, 2018

我們有一個在大型 J2EE 應用程序中執行的 UPDATE 語句,該應用程序被其他語句阻塞。更新使用的是主鍵,所以它應該只影響一行。應用程序中使用的隔離級別應該是 READ UNCOMMITTED,所以它應該只是另一個導致阻塞的修改,但我們看不到在哪裡。

我們已經獲得了所有阻塞事務的報告,這確實表明會話阻塞了更新。使用該DBCC INPUTBUFFER命令顯示了阻塞會話執行的最後一條語句,但這是另一個表上的 SELECT,而不是 UPDATE,所以我認為這不是原因。我認為它必須是交易中較早的聲明。

在這一點上,我的 SQL Server 知識枯竭了,而且我在重現問題時也遇到了問題;它間歇性地發生。

我應該知道採取哪些步驟來找到阻止聲明?

在執行更新之前:

SELECT @@SPID;

現在,執行更新,如果它沒有足夠快地完成,那麼在另一個視窗中執行:

SELECT status, command, wait_type, last_wait_type, blocking_session_id
 FROM sys.dm_exec_requests
 WHERE session_id = <@@SPID from above>;

如果您在 中獲得一個值blocking_session_id,則可以對該 SPID 執行相同的查詢。你也可以說:

DBCC INPUTBUFFER(<blocking spid>);

(好吧,只要您不在 SQL Azure 上。)

如果這沒有產生線索,那麼阻塞語句可能實際上位於更大事務中的不同點。您必須通過確定該 spid 的執行位置以及它是否是一組臨時 T-SQL、儲存過程等來跟踪它。“看這裡”真的沒有什麼神奇的!我們可以為您提供。

如果它沒有被阻止,您可能會在其他列中找到相關資訊,這些資訊可以幫助確定它緩慢的原因(例如,它可能正在等待一個巨大的日誌自動增長事件)。

鑑於我無法將此解釋添加為評論,因此我正在添加答案。但這只是對@Aaron Bertrand 答案的補充:

您的聲明可能正在等待另一個也在等待的聲明。我剛剛添加了 Aaron 的 SELECT 幾次。重複,直到你看到一個正在執行。那可能是問題所在:

Declare @blc int

SELECT @blc = blocking_session_id
FROM sys.dm_exec_requests
WHERE session_id = 109   --Use the SPID here 

SELECT status, command, wait_type, last_wait_type, blocking_session_id
FROM sys.dm_exec_requests
WHERE session_id = @blc

DBCC INPUTBUFFER(@blc);



DECLARE @blc2 int

SELECT @blc2 = blocking_session_id
FROM sys.dm_exec_requests
WHERE session_id = @blc

SELECT status, command, wait_type, last_wait_type, blocking_session_id
FROM sys.dm_exec_requests
WHERE session_id = @blc2

DBCC INPUTBUFFER(@blc2);



DECLARE @blc3 int

SELECT @blc3 = blocking_session_id
FROM sys.dm_exec_requests
WHERE session_id = @blc2

SELECT status, command, wait_type, last_wait_type, blocking_session_id
FROM sys.dm_exec_requests
WHERE session_id = @blc3

DBCC INPUTBUFFER(@blc3);



DECLARE @blc4 int

SELECT @blc4 = blocking_session_id
FROM sys.dm_exec_requests
WHERE session_id = @blc3

SELECT status, command, wait_type, last_wait_type, blocking_session_id
FROM sys.dm_exec_requests
WHERE session_id = @blc4

DBCC INPUTBUFFER(@blc4);

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