數(shù)據(jù)庫常見死鎖原因及處理

數(shù)據(jù)庫是一個多用戶使用的共享資源,當(dāng)多個用戶并發(fā)地存取數(shù)據(jù)時,在數(shù)據(jù)庫中就會產(chǎn)生多個事務(wù)同時存取同一數(shù)據(jù)的情況陨簇。若對并發(fā)操作不加控制就可能會讀取和存儲不正確的數(shù)據(jù)贯吓,破壞數(shù)據(jù)庫的一致性。加鎖是實現(xiàn)數(shù)據(jù)庫并發(fā)控制的一個非常重要的技術(shù)买优。在實際應(yīng)用中經(jīng)常會遇到的與鎖相關(guān)的異常情況,當(dāng)兩個事務(wù)需要一組有沖突的鎖,而不能將事務(wù)繼續(xù)下去的話楚堤,就會出現(xiàn)死鎖,嚴重影響應(yīng)用的正常執(zhí)行含懊。

在數(shù)據(jù)庫中有兩種基本的鎖類型:排它鎖(Exclusive Locks身冬,即X鎖)和共享鎖(Share Locks,即S鎖)岔乔。當(dāng)數(shù)據(jù)對象被加上排它鎖時酥筝,其他的事務(wù)不能對它讀取和修改。加了共享鎖的數(shù)據(jù)對象可以被其他事務(wù)讀取雏门,但不能修改嘿歌。數(shù)據(jù)庫利用這兩種基本的鎖類型來對數(shù)據(jù)庫的事務(wù)進行并發(fā)控制掸掏。

下面總結(jié)下這兩種鎖造成的常見的死鎖情況與解決方案:

一. 事務(wù)之間對資源訪問順序的交替

出現(xiàn)原因:

一個用戶A 訪問表A(鎖住了表A),然后又訪問表B宙帝;另一個用戶B 訪問表B(鎖住了表B)丧凤,然后企圖訪問表A;這時用戶A由于用戶B已經(jīng)鎖住表B步脓,它必須等待用戶B釋放表B才能繼續(xù)愿待,同樣用戶B要等用戶A釋放表A才能繼續(xù),這就死鎖就產(chǎn)生了靴患。

解決方法:

這種死鎖比較常見仍侥,是由于程序的BUG產(chǎn)生的,除了調(diào)整的程序的邏輯沒有其它的辦法鸳君。仔細分析程序的邏輯农渊,對于數(shù)據(jù)庫的多表操作時,盡量按照相同的順序進行處理或颊,盡量避免同時鎖定兩個資源砸紊,如操作A和B兩張表時,總是按先A后B的順序處理囱挑, 必須同時鎖定兩個資源時批糟,要保證在任何時刻都應(yīng)該按照相同的順序來鎖定資源。

二. 并發(fā)修改同一記錄

出現(xiàn)原因:

用戶A查詢一條紀(jì)錄看铆,然后修改該條紀(jì)錄徽鼎;這時用戶B修改該條紀(jì)錄,這時用戶A的事務(wù)里鎖的性質(zhì)由查詢的共享鎖企圖上升到獨占鎖弹惦,而用戶B里的獨占鎖由于A有共享鎖存在所以必須等A釋放掉共享鎖否淤,而A由于B的獨占鎖而無法上升的獨占鎖也就不可能釋放共享鎖,于是出現(xiàn)了死鎖棠隐。這種死鎖由于比較隱蔽石抡,但在稍大點的項目中經(jīng)常發(fā)生。

一般更新模式由一個事務(wù)組成助泽,此事務(wù)讀取記錄啰扛,獲取資源(頁或行)的共享 (S) 鎖,然后修改行嗡贺,此操作要求鎖轉(zhuǎn)換為排它 (X) 鎖隐解。如果兩個事務(wù)獲得了資源上的共享模式鎖,然后試圖同時更新數(shù)據(jù)诫睬,則一個事務(wù)嘗試將鎖轉(zhuǎn)換為排它 (X) 鎖煞茫。共享模式到排它鎖的轉(zhuǎn)換必須等待一段時間,因為一個事務(wù)的排它鎖與其它事務(wù)的共享模式鎖不兼容;發(fā)生鎖等待续徽。第二個事務(wù)試圖獲取排它 (X) 鎖以進行更新蚓曼。由于兩個事務(wù)都要轉(zhuǎn)換為排它 (X) 鎖,并且每個事務(wù)都等待另一個事務(wù)釋放共享模式鎖钦扭,因此發(fā)生死鎖纫版。

解決方法:

a. 使用樂觀鎖進行控制。樂觀鎖大多是基于數(shù)據(jù)版本(Version)記錄機制實現(xiàn)客情。即為數(shù)據(jù)增加一個版本標(biāo)識捎琐,在基于數(shù)據(jù)庫表的版本解決方案中,一般是通過為數(shù)據(jù)庫表增加一個“version”字段來實現(xiàn)裹匙。讀取出數(shù)據(jù)時,將此版本號一同讀出末秃,之后更新時概页,對此版本號加一。此時练慕,將提交數(shù)據(jù)的版本數(shù)據(jù)與數(shù)據(jù)庫表對應(yīng)記錄的當(dāng)前版本信息進行比對惰匙,如果提交的數(shù)據(jù)版本號大于數(shù)據(jù)庫表當(dāng)前版本號,則予以更新铃将,否則認為是過期數(shù)據(jù)项鬼。樂觀鎖機制避免了長事務(wù)中的數(shù)據(jù)庫加鎖開銷(用戶A和用戶B操作過程中,都沒有對數(shù)據(jù)庫數(shù)據(jù)加鎖)劲阎,大大提升了大并發(fā)量下的系統(tǒng)整體性能表現(xiàn)绘盟。Hibernate 在其數(shù)據(jù)訪問引擎中內(nèi)置了樂觀鎖實現(xiàn)。需要注意的是悯仙,由于樂觀鎖機制是在我們的系統(tǒng)中實現(xiàn)龄毡,來自外部系統(tǒng)的用戶更新操作不受我們系統(tǒng)的控制,因此可能會造成臟數(shù)據(jù)被更新到數(shù)據(jù)庫中锡垄。

b. 使用悲觀鎖進行控制沦零。悲觀鎖大多數(shù)情況下依靠數(shù)據(jù)庫的鎖機制實現(xiàn),如Oracle的Select … for update語句货岭,以保證操作最大程度的獨占性路操。但隨之而來的就是數(shù)據(jù)庫性能的大量開銷,特別是對長事務(wù)而言千贯,這樣的開銷往往無法承受屯仗。如一個金融系統(tǒng),當(dāng)某個操作員讀取用戶的數(shù)據(jù)搔谴,并在讀出的用戶數(shù)據(jù)的基礎(chǔ)上進行修改時(如更改用戶賬戶余額)祭钉,如果采用悲觀鎖機制,也就意味著整個操作過程中(從操作員讀出數(shù)據(jù)己沛、開始修改直至提交修改結(jié)果的全過程慌核,甚至還包括操作員中途去煮咖啡的時間)距境,數(shù)據(jù)庫記錄始終處于加鎖狀態(tài),可以想見垮卓,如果面對成百上千個并發(fā)垫桂,這樣的情況將導(dǎo)致災(zāi)難性的后果。所以粟按,采用悲觀鎖進行控制時一定要考慮清楚诬滩。

c. SqlServer可支持更新鎖

為解決死鎖,SqlServer引入更新鎖,它有如下特征:

(1) 加鎖的條件:當(dāng)一個事務(wù)執(zhí)行update語句時灭将,數(shù)據(jù)庫系統(tǒng)會先為事務(wù)分配一把更新鎖疼鸟。

(2) 解鎖的條件:當(dāng)讀取數(shù)據(jù)完畢,執(zhí)行更新操作時庙曙,會把更新鎖升級為獨占鎖空镜。

(3) 與其他鎖的兼容性:更新鎖與共享鎖是兼容的,也就是說捌朴,一個資源可以同時放置更新鎖和共享鎖吴攒,但是最多放置一把更新鎖。這樣砂蔽,當(dāng)多個事務(wù)更新相同的數(shù)據(jù)時洼怔,只有一個事務(wù)能獲得更新鎖,然后再把更新鎖升級為獨占鎖左驾,其他事務(wù)必須等到前一個事務(wù)結(jié)束后镣隶,才能獲取得更新鎖,這就避免了死鎖诡右。

(4) 并發(fā)性能:允許多個事務(wù)同時讀鎖定的資源矾缓,但不允許其他事務(wù)修改它。

例子如下:

T1:
begin tran 
select * from table(updlock) (加更新鎖)
update table setcolumn1='hello'
T2:
begin tran
select * from table(updlock)
update table setcolumn1='world'

更新鎖的意思是:“我現(xiàn)在只想讀稻爬,你們別人也可以讀嗜闻,但我將來可能會做更新操作,我已經(jīng)獲取了從共享鎖(用來讀)到排他鎖(用來更新)的資格”桅锄。一個事物只能有一個更新鎖獲此資格琉雳。

T1執(zhí)行select,加更新鎖友瘤。

T2運行翠肘,準(zhǔn)備加更新鎖,但發(fā)現(xiàn)已經(jīng)有一個更新鎖在那兒了辫秧,只好等束倍。

當(dāng)后來有user3、user4…需要查詢table表中的數(shù)據(jù)時,并不會因為T1的select在執(zhí)行就被阻塞绪妹,照樣能查詢,提高了效率甥桂。

三. 索引不當(dāng)導(dǎo)致全表掃描

出現(xiàn)原因:

如果在事務(wù)中執(zhí)行了一條不滿足條件的語句,執(zhí)行全表掃描邮旷,把行級鎖上升為表級鎖黄选,多個這樣的事務(wù)執(zhí)行后,就很容易產(chǎn)生死鎖和阻塞婶肩。類似的情況還有當(dāng)表中的數(shù)據(jù)量非常龐大而索引建的過少或不合適的時候办陷,使得經(jīng)常發(fā)生全表掃描,最終應(yīng)用系統(tǒng)會越來越慢律歼,最終發(fā)生阻塞或死鎖民镜。

解決方法:

SQL語句中不要使用太復(fù)雜的關(guān)聯(lián)多表的查詢;使用“執(zhí)行計劃”對SQL語句進行分析险毁,對于有全表掃描的SQL語句制圈,建立相應(yīng)的索引進行優(yōu)化。

四.事務(wù)封鎖范圍大且相互等待
https://blog.csdn.net/qq_16681169/article/details/73359670

本文轉(zhuǎn)載至:https://blog.csdn.net/qq_16681169/article/details/74784193

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末辱揭,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子病附,更是在濱河造成了極大的恐慌问窃,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,386評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件完沪,死亡現(xiàn)場離奇詭異域庇,居然都是意外死亡,警方通過查閱死者的電腦和手機覆积,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,142評論 3 394
  • 文/潘曉璐 我一進店門听皿,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人宽档,你說我怎么就攤上這事尉姨。” “怎么了吗冤?”我有些...
    開封第一講書人閱讀 164,704評論 0 353
  • 文/不壞的土叔 我叫張陵又厉,是天一觀的道長。 經(jīng)常有香客問我椎瘟,道長覆致,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,702評論 1 294
  • 正文 為了忘掉前任肺蔚,我火速辦了婚禮煌妈,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己璧诵,他們只是感情好汰蜘,可當(dāng)我...
    茶點故事閱讀 67,716評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著腮猖,像睡著了一般鉴扫。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上澈缺,一...
    開封第一講書人閱讀 51,573評論 1 305
  • 那天坪创,我揣著相機與錄音,去河邊找鬼姐赡。 笑死莱预,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的项滑。 我是一名探鬼主播依沮,決...
    沈念sama閱讀 40,314評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼枪狂!你這毒婦竟也來了危喉?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,230評論 0 276
  • 序言:老撾萬榮一對情侶失蹤州疾,失蹤者是張志新(化名)和其女友劉穎辜限,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體严蓖,經(jīng)...
    沈念sama閱讀 45,680評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡薄嫡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,873評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了颗胡。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片毫深。...
    茶點故事閱讀 39,991評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖毒姨,靈堂內(nèi)的尸體忽然破棺而出哑蔫,到底是詐尸還是另有隱情,我是刑警寧澤弧呐,帶...
    沈念sama閱讀 35,706評論 5 346
  • 正文 年R本政府宣布鸳址,位于F島的核電站,受9級特大地震影響泉懦,放射性物質(zhì)發(fā)生泄漏稿黍。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,329評論 3 330
  • 文/蒙蒙 一崩哩、第九天 我趴在偏房一處隱蔽的房頂上張望巡球。 院中可真熱鬧言沐,春花似錦、人聲如沸酣栈。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,910評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽矿筝。三九已至起便,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間窖维,已是汗流浹背榆综。 一陣腳步聲響...
    開封第一講書人閱讀 33,038評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留铸史,地道東北人鼻疮。 一個月前我還...
    沈念sama閱讀 48,158評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像琳轿,于是被迫代替她去往敵國和親判沟。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,941評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 專業(yè)考題類型管理運行工作負責(zé)人一般作業(yè)考題內(nèi)容選項A選項B選項C選項D選項E選項F正確答案 變電單選GYSZ本規(guī)程...
    小白兔去釣魚閱讀 8,993評論 0 13
  • 關(guān)于Mongodb的全面總結(jié) MongoDB的內(nèi)部構(gòu)造《MongoDB The Definitive Guide》...
    中v中閱讀 31,936評論 2 89
  • 當(dāng)一個系統(tǒng)訪問量上來的時候崭篡,不只是數(shù)據(jù)庫性能瓶頸問題了挪哄,數(shù)據(jù)庫數(shù)據(jù)安全也會浮現(xiàn),這時候合理使用數(shù)據(jù)庫鎖機制就顯得異...
    初來的雨天閱讀 3,571評論 0 22
  • 很少寫過自我描述吧琉闪,大多數(shù)人不能清醒認識自己迹炼,我不然,卻也有正常人的毛病塘偎。張愛玲說過有些話不止該背著別人說疗涉,也該背...
    沐王閱讀 279評論 0 0
  • 時至今日拿霉,仍然時常在夢里出現(xiàn)這樣的畫面吟秩。 一汪河水被太陽照得泛著五彩斑斕的光,岸邊的垂柳绽淘,不甘寂寞的撩動起一圈圈的...
    9小女賊9閱讀 308評論 0 2