當前位置:妙知谷 >

遊戲數碼 >互聯網 >

死鎖產生的原因和解鎖方法

死鎖產生的原因和解鎖方法

產生死鎖的四個必要條件:
(1) 互斥條件:一個資源每次只能被一個進程使用。(2) 請求與保持條件:一個進程因請求資源而阻塞時,對已獲得的資源保持不放。(3) 不剝奪條件:進程已獲得的資源,在末使用完之前,不能強行剝奪。(4) 循環等待條件:若干進程之間形成一種頭尾相接的循環等待資源關係。

操作方法

(01)鎖的類別有兩種分法:  1. 從數據庫系統的角度來看:分為獨佔鎖(即排它鎖),共享鎖和更新鎖  MS-SQL Server 使用以下資源鎖模式。  鎖模式 描述  共享 (S) :讀鎖,用於不更改或不更新數據的操作(只讀操作),如 SELECT 語句。  更新 (U) :(介於共享和排它鎖之間),可以讓其他程序在不加鎖的條件下讀,但本程序可以隨時更改。讀取表時使用更新鎖,而不使用共享鎖,並將鎖一直保留到語句或事務的結束。UPDLOCK 的優點是允許您讀取數據(不阻塞其它事務)並在以後更新數據,同時確保自從上次讀取數據後數據沒有被更改。當我們用UPDLOCK來讀取記錄時可以對取到的記錄加上更新鎖,從而加上鎖的記錄在其它的線程中是不能更改的只能等本線程的事務結束後才能更改,我如下示例:

死鎖產生的原因和解鎖方法

(02)這樣在更新時其它的線程或事務在這些語句執行完成前是不能更改ID是1,2,3的記錄的.其它的都可以修改和讀,1,2,3的只能讀,要是修改的話只能等這些語句完成後才能操作.從而保證的數據的修改正確.排它 (X):寫鎖。 用於數據修改操作,例如 INSERT、UPDATE 或 DELETE。確保不會同時同一資源進行多重更新。  意向鎖 用於建立鎖的層次結構。意向鎖的類型為:意向共享 (IS)、意向排它 (IX) 以及與意向排它共享 (SIX)。  架構鎖 在執行依賴於表架構的操作時使用。架構鎖的類型為:架構修改 (Sch-M) 和架構穩定性 (Sch-S)。  大容量更新 (BU) 向表中大容量複製數據並指定了 TABLOCK 提示時使用。  共享鎖 共享 (S) 鎖允許併發事務讀取 (SELECT) 一個資源。資源上存在共享 (S) 鎖時,任何其它事務都不能修改數據。一旦已經讀取數據,便立即釋放資源上的共享 (S) 鎖,除非將事務隔離級別設置為可重複讀或更高級別,或者在事務生存週期內用鎖定提示保留共享 (S) 鎖。  更新鎖 更新 (U) 鎖可以防止通常形式的死鎖。一般更新模式由一個事務組成,此事務讀取記錄,獲取資源(頁或行)的共享 (S) 鎖,然後修改行,此操作要求鎖轉換為排它 (X) 鎖。如果兩個事務獲得了資源上的共享模式鎖,然後試圖同時更新數據,則一個事務嘗試將鎖轉換為排它 (X) 鎖。共享模式到排它鎖的轉換必須等待一段時間,因為一個事務的排它鎖與其它事務的共享模式鎖不兼容;發生鎖等待。第二個事務試圖獲取排它 (X) 鎖以進行更新。由於兩個事務都要轉換為排它 (X) 鎖,並且每個事務都等待另一個事務釋放共享模式鎖,因此發生死鎖。  若要避免這種潛在的死鎖問題,請使用更新 (U) 鎖。一次只有一個事務可以獲得資源的更新 (U) 鎖。如果事務修改資源,則更新 (U) 鎖轉換為排它 (X) 鎖。否則,鎖轉換為共享鎖。  排它鎖 排它 (X) 鎖可以防止併發事務對資源進行訪問。其它事務不能讀取或修改排它 (X) 鎖鎖定的數據。  意向鎖 意向鎖表示 SQL Server 需要在層次結構中的某些底層資源上獲取共享 (S) 鎖或排它 (X) 鎖。例如,放置在表級的共享意向鎖表示事務打算在表中的頁或行上放置共享 (S) 鎖。在表級設置意向鎖可防止另一個事務隨後在包含那一頁的表上獲取排它 (X) 鎖。意向鎖可以提高性能,因為 SQL Server 僅在表級檢查意向鎖來確定事務是否可以安全地獲取該表上的鎖。而無須檢查表中的每行或每頁上的鎖以確定事務是否可以鎖定整個表。 意向鎖包括意向共享 (IS)、意向排它 (IX) 以及與意向排它共享 (SIX)。

(03)死鎖原理根據操作系統中的定義:死鎖是指在一組進程中的各個進程均佔有不會釋放的資源,但因互相申請被其他進程所站用不會釋放的資源而處於的一種永久等待狀態。死鎖的四個必要條件:互斥條件(Mutual exclusion):資源不能被共享,只能由一個進程使用。請求與保持條件(Hold and wait):已經得到資源的進程可以再次申請新的資源。非剝奪條件(No pre-emption):已經分配的資源不能從相應的進程中被強制地剝奪。循環等待條件(Circular wait):系統中若干進程組成環路,該環路中每個進程都在等待相鄰進程正佔用的資源。對應到SQL Server中,當在兩個或多個任務中,如果每個任務鎖定了其他任務試圖鎖定的資源,此時會造成這些任務永久阻塞,從而出現死鎖;這些資源可能是:單行(RID,堆中的單行)、索引中的鍵(KEY,行鎖)、頁(PAG,8KB)、區結構(EXT,連續的8頁)、堆或B樹(HOBT) 、表(TAB,包括數據和索引)、文件(File,數據庫文件)、應用程序專用資源(APP)、元數據(METADATA)、分配單元(Allocation_Unit)、整個數據庫(DB)。一個死鎖示例如下圖所示:説明:T1、T2表示兩個任務;R1和R2表示兩個資源;由資源指向任務的箭頭(如R1->T1,R2->T2)表示該資源被改任務所持有;由任務指向資源的箭頭(如T1->S2,T2->S1)表示該任務正在請求對應目標資源;    其滿足上面死鎖的四個必要條件:(1).互斥:資源S1和S2不能被共享,同一時間只能由一個任務使用;(2).請求與保持條件:T1持有S1的同時,請求S2;T2持有S2的同時請求S1;(3).非剝奪條件:T1無法從T2上剝奪S2,T2也無法從T1上剝奪S1;(4).循環等待條件:上圖中的箭頭構成環路,存在循環等待。

(04)(1). 根據2中提供的sql,查看那個spid處於wait狀態,然後用kill spid來幹掉(即破壞死鎖的第四個必要條件:循環等待);當然這只是一種臨時解決方案,我們總不能在遇到死鎖就在用户的生產環境上排查死鎖、Kill sp,我們應該考慮如何去避免死鎖。(2). 使用SET LOCK_TIMEOUT timeout_period(單位為毫秒)來設定鎖請求超時。默認情況下,數據庫沒有超時期限(timeout_period值為-1,可以用SELECT @@LOCK_TIMEOUT來查看該值,即無限期等待)。當請求鎖超過timeout_period時,將返回錯誤。timeout_period值為0時表示根本不等待,一遇到鎖就返回消息。設置鎖請求超時,破環了死鎖的第二個必要條件(請求與保持條件)。服務器: 消息 1222,級別 16,狀態 50,行 1已超過了鎖請求超時時段。(3). SQL Server內部有一個鎖監視器線程執行死鎖檢查,鎖監視器對特定線程啟動死鎖搜索時,會標識線程正在等待的資源;然後查找特定資源的所有者,並遞歸地繼續執行對那些線程的死鎖搜索,直到找到一個構成死鎖條件的循環。檢測到死鎖後,數據庫引擎 選擇運行回滾開銷最小的事務的會話作為死鎖犧牲品,返回1205 錯誤,回滾死鎖犧牲品的事務並釋放該事務持有的所有鎖,使其他線程的事務可以請求資源並繼續運行。

特別提示

把SELECT放在Update語句前:SELECT不在事務中,且執行完畢會釋放S鎖

標籤: 死鎖 解鎖
  • 文章版權屬於文章作者所有,轉載請註明 https://miaozhigu.com/sm/hulianwang/79vko.html