SQL SERVER死鎖的追蹤和處理

2021-10-21 18:41:05 字數 1843 閱讀 2160

在程式執行中,發現死鎖,先利用sql server profiler監控;下面是儲存的部分trc檔案的內容,找到死鎖部分:

sql server死鎖表現一:

乙個使用者a 訪問表a(鎖住了表a),然後又訪問表b

另乙個使用者b 訪問表b(鎖住了表b),然後企圖訪問表a

這時使用者a由於使用者b已經鎖住表b,它必須等待使用者b釋放表b,才能繼續,好了他老人家就只好老老實實在這等了

同樣使用者b要等使用者a釋放表a才能繼續這就死鎖了

sql server死鎖解決方法:

這種死鎖是由於你的程式的bug產生的,除了調整你的程式的邏輯別無他法

仔細分析你程式的邏輯,

1:盡量避免同時鎖定兩個資源

2: 必須同時鎖定兩個資源時,要保證在任何時刻都應該按照相同的順序來鎖定資源.

sql server死鎖表現二:

使用者a讀一條紀錄,然後修改該條紀錄

這是使用者b修改該條紀錄

這裡使用者a的事務裡鎖的性質由共享鎖企圖上公升到獨佔鎖(for update),而使用者b裡的獨佔鎖由於a有共享鎖存在所

以必須等a釋

放掉共享鎖,而a由於b的獨佔鎖而無法上公升的獨佔鎖也就不可能釋放共享鎖,於是出現了死鎖。

這種死鎖比較隱蔽,但其實在稍大點的專案中經常發生。

sql server死鎖解決方法:

讓使用者a的事務(即先讀後寫型別的操作),在select 時就是用update lock

語法如下:

select * from table1 with(updlock) where …

這個死鎖是讀取和修改同時競爭資源產生的,屬於第二種,下面的方法,有助於將死鎖減至最少(詳細情況,請看sqlserver聯機幫助,搜尋:將死鎖減至最少即可。

. 按同一順序訪問物件。 

. 避免事務中的使用者互動。

. 保持事務簡短並處於乙個批處理中。

. 使用較低的隔離級別。

. 使用基於行版本控制的隔離級別。

. 將 read_committed_snapshot 資料庫選項設定為 on,使得已提交讀事務使用行版本控制。

. 使用快照隔離。

. 使用繫結連線。

設定資料庫鎖的級別

read_committed_snapshot on

使用基於行版本控制的隔離級別 (sql server 2005 支援 ) :開啟下面的選項後, select 不會對請求的資源加 s 鎖,不加鎖或者加 sch-s 鎖,

從而將讀與寫操作之間發生的死鎖機率降至最低;而且不會發生髒讀

alter database ebcmks set allow_snapshot_isolation on

alter database ebcmks set read_committed_snapshot on

主要是由乙個update和乙個select語句引起了死鎖,這兩條語句執行頻率比較高,主要問題出在這個複雜的查詢和表的資料量上。

目前這種死鎖在我們資料庫裡面還是頻繁的發生。

為處理這種情況,有以下建議:

業務上,是否能夠將該錶的資訊分開,減少資料量;

開發人員能否改進這個查詢語句;

查詢是否可以考慮加上with(nolock),update 語句可以加上 with(rowlock);

其他(考慮分割槽表等)。

最終,將表中資料搬移掉一部分,修改了查詢的語句,同時加上了with(nolock),問題得到解決

SQL Server 中的死鎖

在兩個或多個任務中,如果每個任務鎖定了其他的任務試圖鎖定的資源,會造成這些任務永久阻塞,從而出現死鎖。此時系統處於死鎖狀態。死鎖的原因 在多使用者環境下,死鎖的發生是由於兩個事物都鎖定了不同的資源而又都在申請對方鎖定的資源,即一組程序中的各個程序均占有不會釋放的資源,但因相互申請其他程序占用的不會釋...

關於SQLServer死鎖的診斷和定位

關於 sqlserver 死鎖的診斷和定位 在 sqlserver 中經常會發生死鎖情況,必須連線到企業管理 器 管理 當前活動 鎖 程序 id 去查詢相關死鎖程序和定位死鎖的原因。通過查詢分析器也要經過多個系統表 sysprocesses,sysobjects 等 和系統儲存過程 sp who,s...

sqlserver死鎖阻塞

create proc p lockinfo kill lock spid bit 1,是否殺掉死鎖的程序,1 殺掉,0 僅顯示 show spid if nolock bit 1 如果沒有死鎖的程序,是否顯示正常程序資訊,1 顯示,0 不顯示 as declare count int,s nvar...