原文:
sqlserver中的死鎖的介紹
簡介
什麼是死鎖?
我認為,死鎖是由於兩個物件在擁有乙份資源的情況下申請另乙份資源,而另乙份資源恰好又是這兩物件正持有的,導致兩物件無法完成操作,且所持資源無法釋放。
什麼又是阻塞?
阻塞是由於資源不足引起的排隊等待現象。比如同時兩個程序去更新乙個表。
這裡我們可以把阻塞作為死鎖的必要條件。下面我們先理解一下死鎖和阻塞再來看一下我最近遇到乙個問題以及解決思路。
sqlserver中的死鎖
對應到sql server中,當在兩個或多個任務中,如果每個任務鎖定了其他任務試圖鎖定的資源,此時會造成這些任務永久阻塞,從而出現死鎖;
下面我簡單舉乙個例子來說明一下死鎖的原理:
如圖,按步驟執行:
1. begin tran
update test1 set aaa=1
2.begin tran
update test2 set aaa=1
update test1 set bbb=2
3.再次執行圖1中的update test2 set bbb=2
執行完成後發現資料並未插入,且一直處於running狀態
這個時候我們通過語句查詢死鎖的程序和語句。得到如下結果:
很容易發現發生死鎖的語句,也可以使用sql server profiler 分析死鎖: 將deadlock graph 事件類新增到跟蹤。此事件類使用死鎖涉及到的程序和物件的xml 資料填充跟蹤中的textdata 資料列。sql server 事件探查器可以將xml 文件提取到死鎖xml 檔案中,以後可在sql server management studio 中檢視該檔案。如圖:
接下來我們說一下如何處理死鎖
1.臨時解決方案,先kill 掉死鎖的程序,只是暫時解決這個問題。
2.sql server自動選擇一條sql作死鎖犧牲品:當死鎖發生時,鎖監視器執行緒執行死鎖檢查,資料庫引擎選擇執行回滾開銷最小的事務的會話作為死鎖犧牲品,返回1205 錯誤,回滾死鎖犧牲品的事務並釋放該事務持有的所有鎖,使其他執行緒的事務可以請求資源並繼續執行。
伺服器: 訊息 1205,級別 13,狀態 50,行 1 事務(程序 id xx)與另乙個程序已被死鎖在 lock 資源上,且該事務已被選作死鎖犧牲品。請重新執行該事務。
3.使用set lock_timeout timeout_period(單位為毫秒)來設定請求超時。
4.在sqlserver 和程式兩個方面都可以做**上修正,這裡不在詳細描述,主要是通過發現死鎖等待一段時間後再次嘗試的方式來解決。
預防和避免死鎖
1.儘量減少事務執行的時間。
2.在合理的範圍內降低隔離級別。
3.同乙個事務內盡量避免出現迴圈對同乙個表的處理。
4.同乙個事務內較少使用者互動,即鎖的競爭。
5.盡量保證邏輯處理的順序比如對錶的處理都按照乙個順序進行。
6.對於需要各種邏輯處理的表,可以通過增加索引的方式來減少鎖的競爭。
7.儘量減少非聚集索引的include 的列,也能減少外來鍵死鎖的發生。
8.同乙個物件盡量採用select 在update 前來使用。
9.對於實時性要求不高的可以使用with(nolock)來實現對錶的查詢,但是可能會差生髒讀。
總結
本文簡單的介紹了死鎖的原因,如何解決和預防。當然任何事情都是雙刃劍,還要我們根據實際情況來合理減少死鎖和阻塞的發生;對於不同隔離界別鎖帶來的問題可以看一下我之前的一篇關於鎖的介紹。希望對死鎖發生預防和解決有一定的幫助。
SQL Server 中的死鎖
在兩個或多個任務中,如果每個任務鎖定了其他的任務試圖鎖定的資源,會造成這些任務永久阻塞,從而出現死鎖。此時系統處於死鎖狀態。死鎖的原因 在多使用者環境下,死鎖的發生是由於兩個事物都鎖定了不同的資源而又都在申請對方鎖定的資源,即一組程序中的各個程序均占有不會釋放的資源,但因相互申請其他程序占用的不會釋...
sqlserver中select造成死鎖
專案上線,準備驗收前出現了乙個嚴重的問題 很多select語句作為死鎖的犧牲,大部分報表無法開啟。這個問題影響範圍很大所有的報表都無法訪問,而我們的報表是放在電視上面輪播的,電視放在工廠裡面,所以出現問題後,整個工廠都知道了。解決這個問題比較曲折,首先是寫sap介面的同事發現了問題 sap一直在傳錯...
sqlserver中select造成死鎖
死鎖過程 於是只要讓查詢語句加共享鎖就解決問題了,sql server行版本級別控制能解決我的問題。使用基於行版本控制的隔離級別 當在基於行版本控制的隔離下執行的事務讀取資料時,讀取操作不會獲取正被讀取的資料上的共享鎖 s 鎖 找到最快設定行版本級別的方法 if charindex microsof...