佳木斯湛栽影视文化发展公司

主頁 > 知識庫 > MySQL死鎖的產(chǎn)生原因以及解決方案

MySQL死鎖的產(chǎn)生原因以及解決方案

熱門標(biāo)簽:AI電銷 鐵路電話系統(tǒng) 網(wǎng)站排名優(yōu)化 服務(wù)外包 地方門戶網(wǎng)站 Linux服務(wù)器 百度競價排名 呼叫中心市場需求

數(shù)據(jù)庫和操作系統(tǒng)一樣,是一個多用戶使用的共享資源。當(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á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ù)進(jìn)行并發(fā)控制。

死鎖的第一種情況

一個用戶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)整的程序的邏輯沒有其它的辦法。仔細(xì)分析程序的邏輯,對于數(shù)據(jù)庫的多表操作時,盡量按照相同的順序進(jìn) 行處理,盡量避免同時鎖定兩個資源,如操作A和B兩張表時,總是按先A后B的順序處理, 必須同時鎖定兩個資源時,要保證在任何時刻都應(yīng)該按照相同的順序來鎖定資源。

死鎖的第二種情況

用戶A查詢一條紀(jì)錄,然后修改該條紀(jì)錄;這時用戶B修改該條紀(jì)錄,這時用戶A的事務(wù)里鎖的性質(zhì)由查詢的共享鎖企圖上升到獨占鎖,而用戶B里的獨占鎖由于A 有共享鎖存在所以必須等A釋放掉共享鎖,而A由于B的獨占鎖而無法上升的獨占鎖也就不可能釋放共享鎖,于是出現(xiàn)了死鎖。這種死鎖比較隱蔽,但在稍大點的項 目中經(jīng)常發(fā)生。如在某項目中,頁面上的按鈕點擊后,沒有使按鈕立刻失效,使得用戶會多次快速點擊同一按鈕,這樣同一段代碼對數(shù)據(jù)庫同一條記錄進(jìn)行多次操 作,很容易就出現(xiàn)這種死鎖的情況。

解決方法:

1、對于按鈕等控件,點擊后使其立刻失效,不讓用戶重復(fù)點擊,避免對同時對同一條記錄操作。

2、使用樂觀鎖進(jìn)行控制。樂觀鎖大多是基于數(shù)據(jù)版本(Version)記錄機(jī)制實現(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)前版本信息進(jìn)行比對,如果提交的數(shù)據(jù)版本號大于數(shù)據(jù)庫表當(dāng)前版本號,則予以更新,否則認(rèn)為是過期數(shù)據(jù)。樂觀鎖機(jī)制避免了長事務(wù)中的數(shù)據(jù) 庫加鎖開銷(用戶A和用戶B操作過程中,都沒有對數(shù)據(jù)庫數(shù)據(jù)加鎖),大大提升了大并發(fā)量下的系統(tǒng)整體性能表現(xiàn)。Hibernate 在其數(shù)據(jù)訪問引擎中內(nèi)置了樂觀鎖實現(xiàn)。需要注意的是,由于樂觀鎖機(jī)制是在我們的系統(tǒng)中實現(xiàn),來自外部系統(tǒng)的用戶更新操作不受我們系統(tǒng)的控制,因此可能會造 成臟數(shù)據(jù)被更新到數(shù)據(jù)庫中。

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

死鎖的第三種情況

如果在事務(wù)中執(zhí)行了一條不滿足條件的update語句,則執(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語句進(jìn)行分析,對于有全表掃描的SQL語句,建立相應(yīng)的索引進(jìn)行優(yōu)化。

小結(jié)

總體上來說,產(chǎn)生內(nèi)存溢出與鎖表都是由于代碼寫的不好造成的,因此提高代碼的質(zhì)量是最根本的解決辦法。有的人認(rèn)為先把功能實現(xiàn),有BUG時再在測試階段進(jìn) 行修正,這種想法是錯誤的。正如一件產(chǎn)品的質(zhì)量是在生產(chǎn)制造的過程中決定的,而不是質(zhì)量檢測時決定的,軟件的質(zhì)量在設(shè)計與編碼階段就已經(jīng)決定了,測試只是 對軟件質(zhì)量的一個驗證,因為測試不可能找出軟件中所有的BUG。

以上就是MySQL死鎖的產(chǎn)生原因以及解決方案的詳細(xì)內(nèi)容,更多關(guān)于MySQL死鎖的資料請關(guān)注腳本之家其它相關(guān)文章!

您可能感興趣的文章:
  • Mysql查看死鎖與解除死鎖的深入講解
  • MySQL死鎖檢查處理的正常方法
  • 關(guān)于MySQL死鎖問題的深入分析
  • MySQL死鎖套路之唯一索引下批量插入順序不一致
  • 一個mysql死鎖場景實例分析
  • 一次神奇的MySQL死鎖排查記錄
  • MySQL數(shù)據(jù)庫之Purge死鎖問題解析
  • 詳解通過SQL進(jìn)行分布式死鎖的檢測與消除

標(biāo)簽:崇左 黃山 仙桃 湘潭 銅川 湖南 衡水 蘭州

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《MySQL死鎖的產(chǎn)生原因以及解決方案》,本文關(guān)鍵詞  ;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請?zhí)峁┫嚓P(guān)信息告之我們,我們將及時溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無關(guān)。
  • 相關(guān)文章
  • 收縮
    • 微信客服
    • 微信二維碼
    • 電話咨詢

    • 400-1100-266
    丰台区| 永丰县| 沽源县| 宜兴市| 承德县| 西青区| 曲阳县| 阳山县| 科尔| 揭阳市| 宁城县| 古丈县| 科技| 德惠市| 武宣县| 屏东市| 左权县| 商河县| 克山县| 平和县| 隆回县| 麻江县| 武功县| 木里| 金昌市| 凤冈县| 巧家县| 烟台市| 柳河县| 涞水县| 黄冈市| 古交市| 毕节市| 靖宇县| 常德市| 安泽县| 扶绥县| 外汇| 安乡县| 博兴县| 广水市|