SQLServer中的死锁的介绍
簡(jiǎn)介
???? 什么是死鎖?
???? 我認(rèn)為,死鎖是由于兩個(gè)對(duì)象在擁有一份資源的情況下申請(qǐng)另一份資源,而另一份資源恰好又是這兩對(duì)象正持有的,導(dǎo)致兩對(duì)象無(wú)法完成操作,且所持資源無(wú)法釋放。
????? 什么又是阻塞?
?????阻塞是由于資源不足引起的排隊(duì)等待現(xiàn)象。比如同時(shí)兩個(gè)進(jìn)程去更新一個(gè)表。
???? 這里我們可以把阻塞作為死鎖的必要條件。下面我們先理解一下死鎖和阻塞再來(lái)看一下我最近遇到一個(gè)問(wèn)題以及解決思路。
SQLServer中的死鎖
?????對(duì)應(yīng)到SQL Server中,當(dāng)在兩個(gè)或多個(gè)任務(wù)中,如果每個(gè)任務(wù)鎖定了其他任務(wù)試圖鎖定的資源,此時(shí)會(huì)造成這些任務(wù)永久阻塞,從而出現(xiàn)死鎖;
???這些資源可能是:單行(RID,堆中的單行)、索引中的鍵(KEY,行鎖)、頁(yè)(PAG,8KB)、區(qū)結(jié)構(gòu)(EXT,連續(xù)的8頁(yè))、堆或B樹(shù)(HOBT) 、表(TAB,包括數(shù)據(jù)和索引)、文件(File,數(shù)據(jù)庫(kù)文件)、應(yīng)用程序?qū)S觅Y源(APP)、元數(shù)據(jù)(METADATA)、分配單元(Allocation_Unit)、整個(gè)數(shù)據(jù)庫(kù)(DB)。
??? 下面我簡(jiǎn)單舉一個(gè)例子來(lái)說(shuō)明一下死鎖的原理:
????
?
?如圖,按步驟執(zhí)行:
1. begin tran
update test1 set aaa=1
2.
begin tran
update test2 set aaa=1
update test1 set bbb=2
3.再次執(zhí)行圖1中的Update test2 set bbb=2
執(zhí)行完成后發(fā)現(xiàn)數(shù)據(jù)并未插入,且一直處于running狀態(tài)
?
這個(gè)時(shí)候我們通過(guò)語(yǔ)句查詢死鎖的進(jìn)程和語(yǔ)句。得到如下結(jié)果:
?
很容易發(fā)現(xiàn)發(fā)生死鎖的語(yǔ)句,也可以使用 SQL Server Profiler 分析死鎖: 將 Deadlock graph 事件類添加到跟蹤。此事件類使用死鎖涉及到的進(jìn)程和對(duì)象的 XML 數(shù)據(jù)填充跟蹤中的 TextData 數(shù)據(jù)列。SQL Server 事件探查器?可以將 XML 文檔提取到死鎖 XML? 文件中,以后可在 SQL Server Management Studio 中查看該文件。如圖:
接下來(lái)我們說(shuō)一下如何處理死鎖
????? 1.臨時(shí)解決方案,先Kill 掉死鎖的進(jìn)程,只是暫時(shí)解決這個(gè)問(wèn)題。
????? 2.SQL Server自動(dòng)選擇一條SQL作死鎖犧牲品:當(dāng)死鎖發(fā)生時(shí),鎖監(jiān)視器線程執(zhí)行死鎖檢查,數(shù)據(jù)庫(kù)引擎?選擇運(yùn)行回滾開(kāi)銷最小的事務(wù)的會(huì)話作為死鎖犧牲品,返回1205 錯(cuò)誤,回滾死鎖犧牲品的事務(wù)并釋放該事務(wù)持有的所有鎖,使其他線程的事務(wù)可以請(qǐng)求資源并繼續(xù)運(yùn)行。
服務(wù)器:?消息?1205,級(jí)別?13,狀態(tài)?50,行?1 事務(wù)(進(jìn)程?ID??xx)與另一個(gè)進(jìn)程已被死鎖在??lock?資源上,且該事務(wù)已被選作死鎖犧牲品。請(qǐng)重新運(yùn)行該事務(wù)。???? 3.使用SET LOCK_TIMEOUT timeout_period(單位為毫秒)來(lái)設(shè)定請(qǐng)求超時(shí)。?
???? 4.在SQLServer 和程序兩個(gè)方面都可以做代碼上修正,這里不在詳細(xì)描述,主要是通過(guò)發(fā)現(xiàn)死鎖等待一段時(shí)間后再次嘗試的方式來(lái)解決。
預(yù)防和避免死鎖
???? 1.盡量減少事務(wù)執(zhí)行的時(shí)間。
?????2.在合理的范圍內(nèi)降低隔離級(jí)別。
???? 3.同一個(gè)事務(wù)內(nèi)盡量避免出現(xiàn)循環(huán)對(duì)同一個(gè)表的處理。
???? 4.同一個(gè)事務(wù)內(nèi)較少用戶交互,即鎖的競(jìng)爭(zhēng)。
???? 5.盡量保證邏輯處理的順序比如對(duì)表的處理都按照一個(gè)順序進(jìn)行。
???? 6.對(duì)于需要各種邏輯處理的表,可以通過(guò)增加索引的方式來(lái)減少鎖的競(jìng)爭(zhēng)。
???? 7.盡量減少非聚集索引的include 的列,也能減少外鍵死鎖的發(fā)生。
???? 8.同一個(gè)對(duì)象盡量采用select 在update 前來(lái)使用。
???? 9.對(duì)于實(shí)時(shí)性要求不高的可以使用with(nolock)來(lái)實(shí)現(xiàn)對(duì)表的查詢,但是可能會(huì)差生臟讀。
?
?總結(jié)
????? 本文簡(jiǎn)單的介紹了死鎖的原因,如何解決和預(yù)防。當(dāng)然任何事情都是雙刃劍,還要我們根據(jù)實(shí)際情況來(lái)合理減少死鎖和阻塞的發(fā)生;對(duì)于不同隔離界別鎖帶來(lái)的問(wèn)題可以看一下我之前的一篇關(guān)于鎖的介紹。希望對(duì)死鎖發(fā)生預(yù)防和解決有一定的幫助。
轉(zhuǎn)載于:https://www.cnblogs.com/wenBlog/p/5217103.html
總結(jié)
以上是生活随笔為你收集整理的SQLServer中的死锁的介绍的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: ios 微信支付
- 下一篇: linux cmake编译源码,linu