【MS SQL】處理SQL DeadLock

處理SQL DeadLock

今天是我的到職第一年。(晚點再發感慨文)

手上維護的案子,其實平常資料流量頗大,而且也有部分使用了SQL Truncation機制。

系統已經有一個老問題(此系統已經運行七八年之久),可是卻一直沒有很正式的處理&排除。

那就是在資料處理時,時常會有DeadLock的情形發生。

今天終於下定決心來處理。

平常,基本上的Select語法已經有套用With(NoLock)結避免。

PS:使用With(NoLock)是有風險的。可能造成資料不一致。

原因是,加了With(NoLock)會將忽略鎖定後的資料。

可能造成,資料不一致。請參考:RiCo技術農場

回到本文,其實處理DeadLock在我的想法中很困難。

主管給了我一條明路。

請參考:黑暗執行緒(愛逛的BLOG之一啊!!)

整體操作流程就跟黑大文章記載的一樣。

補充一點:SQL2008有內建的範本請見圖。(選擇TSQL_Locks)

或這是使用空白的範本,自行定義事件選取範圍。

我這次因為機器上為SQL2005,所以,基本上我選取的事件範圍跟黑大設定的一樣。

之後就開始執行。

執行過程,可以很清楚的看見所有執行過的Query(用過Profiler的人會跟我說這是廢話)。

今天在很有耐心的終於等到DeadLock出現(平常看到這個都很無奈,第一次看到他好快樂)。

結果也跟黑大的文章擷取的畫面一致。

找到EventClass=Deadlock graph點到那一個資料列下方會很清楚的出現衝突的SPID&指令,還有被犧牲的SPID。

不過,感覺指令並沒有顯示完全。

沒有意外,DeadLock是發生在我原本預計的SQL指令中。

這段指令是用一個Trancation包起來。

當中,流程大約是:

  1. Update TableA
  2. Update TableA
  3. Update TableB
  4. Update TableC set XXX=@XXX where ID=@ID
  5. Delete TableC Where 某區間

兩個衝突的指令是一樣的,只是Where 條件不同。

該錯誤顯示出是TableC 的主鍵被鎖定。

菜菜的推論是Delete誤了事。

由於,該Delete其實不用每次做這件資料處理就執行一次。

目前解決方式:

1.將上述指令5另外做一個Store Procedure並且設定排程執行。

2.將上述指令5移除每次執行的動作。

再來就是持續觀察啦!

希望菜菜的我想的沒錯。

 

 

以上文章若有任何錯誤或指教歡迎留言糾正!!

必定欣然學習求教。