前言
終于進入死鎖系列,前面也提到過我一直對隔離級別和死鎖以及如何避免死鎖等問題模棱兩可,所以才鼓起了重新學習SQL Server系列的勇氣,本節(jié)我們來講講SQL Server中的死鎖,看到許多文章都只簡述不能這樣做,這樣做會導致死鎖,但是未理解其基本原理,下次遇到類似情況依然會犯錯,所以基于了解死鎖原理并且得到治療死鎖良方,博主不惜花費多天時間來學習死鎖最終總結出本文,若有敘述不當之處請在評論中指出。
死鎖定義
死鎖是兩個或多個進程互相阻塞的情況。兩個進程死鎖的例子是,進程A阻塞進程B且進程B阻塞進程B。涉及多個進程死鎖的例子是,進程A阻塞進程B,進程B阻塞進程C且進程C阻塞進程A。在任何一種情況下,SQL Server檢測到死鎖,都會通過終止其中的一個事務盡心干預。如果SQL Server不干預,涉及的進程永遠陷于死鎖狀態(tài)。
除外另外指定,SQL Server選擇終止工作最少的事務,因為它便于回滾該事務的工作。但是,SQL Server允許用戶設置一個叫做DEADLOCK_PRIORITY的會話選項,可以是范圍在-10~10之間的21個值中的任意值,死鎖優(yōu)先級最低的進程將被作為犧牲對象,而不管其做了多少工作。我們可以舉一個生活中常見和死鎖類似的例子,當在車道上行駛時,快到十字路口的紅燈時,此時所有的小車都已經(jīng)就緒等待紅燈,當變綠燈時,此時有駕駛員發(fā)現(xiàn)走錯了車道,于是開始變換車道,但是別的車道都擁堵在一塊根本插不進去,駕駛員只有等待有空隙時再插進去,同時駕駛員車道上后面的小車又在等待駕駛員開到別的車道。這種情況雖然不恰當,但是在一定程度上很好的表現(xiàn)了死鎖的情況,所以在開車時盡量別吵吵,否則誰都走不了,keep silence。
下面我們來演示常見的一種死鎖情況,然后我們再來討論如何減少系統(tǒng)中死鎖的發(fā)生。