前段時間提到的"sql server 2005 死鎖解決探索",死鎖嚴重,平均天天會發生一次死鎖,在解決和處理SQL server2005死鎖中查了不少資料和想了不少辦法, 對爲什麼出現死鎖和怎樣較少死鎖有了進一步認識,在這裏和你們一塊兒分享:
sql server 鎖類型 在數據庫中主要存在兩種鎖: S(共享鎖)和X(排他鎖) S(共享鎖):在執行查詢數據時,sql server會將行鎖定,這時只能查詢數據,刪,改被阻塞, X(排他鎖):在插入和刪除數據時,將行鎖定,這時增,刪,改都被阻塞 以上兩種鎖都會引發死鎖: 死鎖定義:在兩個或多個任務中,若是每一個任務鎖定了其餘任務試圖鎖定的資源,此時會形成這些任務永久阻塞,從而出現死鎖 這裏模擬一下死鎖環境: 創建環境: ----死鎖例子,創建表數據 create table [dbo].[[zping.com1]]]( A varchar(2) ,B varchar(2) ,C varchar(2)) --插入數據 insert into [dbo].[[zping.com1]]] select 'a1','b1','c1' union all select 'a2','b2','c2' union all select 'a3','b3','c3' --創建表數據 create table [dbo].[[zping.com2]]] (D varchar(2) ,E varchar(2)) --插入數據 insert into [dbo].[[zping.com2]]] select 'd1','e1' union all select 'd2','e2' 1. 1 排他鎖引發的死鎖 執行語句: begin tran update [dbo].[[zping.com2]]] set D='d5' where E='e1' waitfor delay '00:00:05' update [dbo].[[zping.com1]]] set A='aa' where B='b2' begin tran update [dbo].[[zping.com1]]] set A='aa' where B='b2' waitfor delay '00:00:05' update [dbo].[[zping.com2]]] set D='d5' where E='e1' 新建兩個窗口,在5秒鐘內執行上面語句,不久就會出現死鎖提示。(結束後記住要把事務回滾啊) 1.2 共享鎖引發的死鎖 begin tran update [dbo].[[zping.com2]]] set D='d5' where E='e1' waitfor delay '00:00:05' select * from [dbo].[[zping.com1]]] where B='b2' begin tran update [dbo].[[zping.com1]]] set A='aa' where B='b2' waitfor delay '00:00:05' select * from [dbo].[[zping.com2]]] where E='e1' 新建兩個窗口,在5秒鐘內執行上面語句。不久就會出現死鎖提示。(結束後記住要把事務回滾啊) 知道死鎖產生的緣由,在生產環境產生的死鎖就相似這兩種狀況。 後來在網上查閱了不少資料,包括sql server 2005的幫助文檔。總結有如下有主要幾點: 1,下降隔離級別或者使用行版本控制隔離級別 2,提升數據的訪問速度 3,減小事務長度 4,將按順序訪問熱點表(如將訪問頻繁的表放在最後訪問) 遇到的困難 但在咱們此次優化中,有些是不太好處理的 如: 1,減小事務長度,事務的大小不是咱們來決定的,是由業務邏輯來決定的(來自tom的《Oracle 9i/10g深刻內部體系機構》中) 2,按順序訪問熱點表,咱們發現代碼中方法間互相調用很頻繁,常常一個表調用屢次,要修改表的訪問順序是比較困難的。 採用的方法 後來咱們就使用瞭如下方法: 1,將數據庫隔離級別改爲行版本控制隔離級別。(沒有了共享鎖死鎖) 2,重建和優化索引,優化SQL語句和採用分區視圖等方法。提升訪問速度。(減小了鎖定時間) 3,水平拆分表(分區)並在程序讀寫時儘可能作到分區消除,減小讀寫的行數,下降鎖定升級的頻率和時間。 (減小鎖的升級) 經過4個月左右的運行,系統就發生過一次死鎖,比之前大大下降