知方可補不足~用SqlProfiler來監(jiān)視數(shù)據(jù)庫死鎖
關(guān)于鎖的相關(guān)知識,大家可以看我的這篇文章《知方可補不足~Sqlserver中的幾把鎖和.net中的事務(wù)級別》
死鎖我想大家都知道,當(dāng)一個對話(線程)占用一個資源時,別一個線程也同時去訪問它,并且其中一個優(yōu)化級高的對話將SQL鎖狀態(tài)提升為X鎖(排它鎖)后,其一個對話將會被作為“犧牲品”拋棄,這種現(xiàn)象在SQLSERVER中就叫做死鎖,引起死鎖的原因有很多,一般在網(wǎng)上被前人總結(jié)為四點
1、互斥使用(資源獨占)
一個資源每次只能給一個進(jìn)程使用
2、不可強占(不可剝奪)
資源申請者不能強行的從資源占有者手中奪取資源,資源只能由占有者自愿釋放
3、請求和保持(部分分配,占有申請)
一個進(jìn)程在申請新的資源的同時保持對原有資源的占有(只有這樣才是動態(tài)申請,動態(tài)分配)
4、循環(huán)等待
存在一個進(jìn)程等待隊列 {P1 , P2 , … , Pn}, 其中P1等待P2占有的資源,P2等待P3占有的資源,…,Pn等待P1占有的資源,形成一個進(jìn)程等待環(huán)路
觀察鎖的發(fā)生,使用sqlProfiler工具
設(shè)置對話(線程,spid)的優(yōu)先級
SET TRANSACTION ISOLATION LEVEL Read Committed
BEGIN TRAN
SET DEADLOCK_PRIORITY HIGH
對于優(yōu)先級,以以下選項
LOW | NORMAL | HIGH
也可以直接使用數(shù)字
<numeric-priority> ::= { -10 | -9 | -8 | …| 0 | …| 8 | 9 | 10 }
在EF里,對發(fā)生死鎖的代碼進(jìn)行重新提交
在EF架構(gòu)里,倉儲大叔提倡大家使用自己的SaveChanges方法,其原因就是可以對提交動作進(jìn)行統(tǒng)一的控制,在里面加日志,加捕捉,加策略可以成為可能,呵呵。
//下面代碼節(jié)選自大叔的DbContextRepository類 catch (EntityException ex)//EF配置異常,這個異常可以忽略(The underlying provider failed on Commit.) { if (Logger != null) Logger(ex.Message); throw new Exception(ex.Message);//EntityException } catch (Exception ex)//捕獲所有異常 { if (Logger != null)//如果沒有定義日志功能,就把異常拋出來吧 Logger(ex.Message + "處理時間:" + DateTime.Now); if (ex.GetBaseException() != null && ex.GetBaseException().GetType() == typeof(System.Data.SqlClient.SqlException)) { //SqlException異常,再重新進(jìn)行提交 Db.SaveChanges(); } throw new Exception(ex.Message); }
浙公網(wǎng)安備 33010602011771號