找回密碼
 註冊

SQL Server Deadlock 問題探討

来源: 新聞 跑山的節奏 2011-9-8 09:18 只看這個作者 只看大圖 |閱讀模式
2 4596
本文最後由 編輯部女孩 於 2016-9-1 16:58 編輯

今天假設某A跟某B使用SQL"update"
兩人各LOCK一個資料表
尚未做commit OR rollback
用紅色線代表
這時又要去更改對方的資料表
用藍色線代表
這時就會進入死結狀態
SQL Server Deadlock 問題探討1486
想探討此狀態的解決方法
就像一條小路上,兩台汽車相會總是要一台車退讓
所以會有一方犧牲掉,傳錯誤訊息請對方重新操作
我的想法是,能不能把兩人所使用的操作利用緩存的方式先存起來,並回傳訊息告知操作者
等到兩人都操作完畢
系統再對於那兩筆緩存依據資料表欄位時間先後更新資料
想請問大家,那有沒有其他方式可以解決呢??
收藏
收藏0

網友回覆2

跳到指定樓層
2#
Cloud 2011-9-8 10:07 只看這個作者
本文最後由 編輯部女孩 於 2016-9-1 16:58 編輯

這樣不行啦...你用緩衝的方式,沒辦法保證A、B看到的,都是最新最即時的資料
假設T1裡面有一筆資料,其欄位值是 X ; T2裡面有一筆資料,其欄位值是 Y。
A 想要將 X 改成 Z & 也想把T2內的Y改成H。
B 想要將Y改成W & 也想把T1內的X改成G。
若使用緩存指令的方法來做的話...
A所下的語法 :  
update T1 set 欄位名稱 = Z where 欄位名稱 = X ; 10點整執行
update T2 set 欄位名稱 = H where 欄位名稱 = Y; 10點15分執行
B所下的語法 :  
update T1 set 欄位名稱 = G where 欄位名稱 = X ; 10點05分執行
update T2 set 欄位名稱 = W where 欄位名稱 = Y ; 10點10分執行
接著在排列一下執行的先後順序...
A : update T1 set 欄位名稱 = Z where 欄位名稱 = X ; 10點整執行
B : update T1 set 欄位名稱 = G where 欄位名稱 = X ; 10點05分執行
此時在10點05分要執行B的指令時,就會有錯誤產生...
因為X已經被改成Z了,導致根本就沒有符合『where 欄位名稱 = X』的結果出現...
同理可證...T2也是有同樣的問題發生。
本文最後由 編輯部女孩 於 2016-9-1 16:59 編輯

這樣不行啦...你用緩衝的方式,沒辦法保證A、B看到的,都是最新最即時的資料
假設T1裡面有一筆資料,其欄位值是 X ; T2裡面有一筆資料,其欄位值是 Y。
A 想要將 X 改成 Z & 也想把T2內的Y改成H。
B 想要將Y改成W & 也想把T1內的X改成G。
若使用緩存指令的方法來做的話...
A所下的語法 :  
update T1 set 欄位名稱 = Z where 欄位名稱 = X ; 10點整執行
update T2 set 欄位名稱 = H where 欄位名稱 = Y; 10點15分執行
B所下的語法 :  
update T1 set 欄位名稱 = G where 欄位名稱 = X ; 10點05分執行
update T2 set 欄位名稱 = W where 欄位名稱 = Y ; 10點10分執行
接著在排列一下執行的先後順序...
A : update T1 set 欄位名稱 = Z where 欄位名稱 = X ; 10點整執行
B : update T1 set 欄位名稱 = G where 欄位名稱 = X ; 10點05分執行
此時在10點05分要執行B的指令時,就會有錯誤產生...
因為X已經被改成Z了,導致根本就沒有符合『where 欄位名稱 = X』的結果出現...
同理可證...T2也是有同樣的問題發生。 [/quote]
那個~您的假設情況有誤喔
因為今天A是從T1開始更新,B是從T2開始更新
所以時間要改成這樣
A所下的語法 :  
update T1 set 欄位名稱 = Z where 欄位名稱 = X ; 10點整執行
update T2 set 欄位名稱 = H where 欄位名稱 = Y; 10點15分執行
B所下的語法 :  
update T1 set 欄位名稱 = G where 欄位名稱 = X ; 10點10分執行
update T2 set 欄位名稱 = W where 欄位名稱 = Y ; 10點05分執行
整理後變這樣
資料表:       T1   T2
原始資料:     X    Y
10:00更新:    Z    Y
10:05更新:    Z    W
到這邊應該是沒有問題的
接下來的 10:10 10:15 兩筆指令衝突
因為已經沒有X跟Y
就常理來說,時間最晚的那一筆資料才會保存,其他的會被覆蓋
也就是說
針對T1.T2資料表
A想在10點整把X改成Z    B想在10點10把X改成G  依據常理來說,最後的資料會是G
一樣的情況
B想在10點05把Y改成W   A想在10點15把Y改成H  依據常理來說,最後的資料會是H
我說的時間先後判斷是依照資料表欄位被更新的時間(這點好像並未說清楚,抱歉讓您誤會了)
所以系統判斷後抓的是     把X改成G    and    把Y改成H  
不然另外一種方式就是
A先把X改成Z,系統自動幫B把指令中的X改為Z,那B的指令會是把Z改成G
但是有沒有辦法成功我就不清楚了
工程師就是無中生有最厲害
說不定真有辦法