資料庫鎖表的分析與解決

2022-07-30 13:21:11 字數 2193 閱讀 6325

資料庫鎖表的分析與解決

上面介紹了記憶體溢位的原因和處理方法,下面再介紹一下資料庫鎖表及阻塞的原因和處理辦法。

資料庫和作業系統一樣,是乙個多使用者使用的共享資源。當多個使用者併發地訪問資料時,在資料庫中就會產生多個事務同時訪問同一資料的情況。若對併發操作不加控制就可能會讀取和儲存不正確的資料,破壞資料庫的一致性。加鎖是實現資料庫併發控制的乙個非常重要的技術。在實際應用中經常會遇到的與鎖相關的異常情況,當兩個事務需要一組有衝突的鎖,而不能將事務繼續下去的話,就會出現死鎖,嚴重影響應用的正常執行。

在資料庫中有兩種基本的鎖型別:排它鎖(exclusive locks,即x鎖)和共享鎖(share locks,即s鎖)。當資料物件被加上排它鎖時,其他的事務不能對它讀取和修改。加了共享鎖的資料物件可以被其他事務讀取,但不能修改。資料庫利用這兩種基本的鎖型別來對資料庫的事務進行併發控制。

死鎖的第一種情況

乙個使用者a 訪問表a(鎖住了表a),然後又訪問表b;另乙個使用者b 訪問表b(鎖住了表b),然後企圖訪問表a;這時使用者a由於使用者b已經鎖住表b,它必須等待使用者b釋放表b才能繼續,同樣使用者b要等使用者a釋放表a才能繼續,這就死鎖就產生了。

解決方法:

這種死鎖比較常見,是由於程式的bug產生的,除了調整的程式的邏輯沒有其它的辦法。仔細分析程式的邏輯,對於資料庫的多表操作時,盡量按照相同的順序進行處理,盡量避免同時鎖定兩個資源,如操作a和b兩張表時,總是按先a後b的順序處理, 必須同時鎖定兩個資源時,要保證在任何時刻都應該按照相同的順序來鎖定資源。

死鎖的第二種情況

使用者a查詢一條紀錄,然後修改該條紀錄;這時使用者b修改該條紀錄,這時使用者a的事務裡鎖的性質由查詢的共享鎖企圖上公升到獨佔鎖,而使用者b裡的獨佔鎖由於a有共享鎖存在所以必須等a釋放掉共享鎖,而a由於b的獨佔鎖而無法上公升的獨佔鎖也就不可能釋放共享鎖,於是出現了死鎖。這種死鎖比較隱蔽,但在稍大點的專案中經常發生。如在某專案中,頁面上的按鈕點選後,沒有使按鈕立刻失效,使得使用者會多次快速點選同一按鈕,這樣同一段**對資料庫同一條記錄進行多次操作,很容易就出現這種死鎖的情況。

解決方法:

1、對於按鈕等控制項,點選後使其立刻失效,不讓使用者重複點選,避免對同時對同一條記錄操作。

2、使用樂觀鎖進行控制。樂觀鎖大多是基於資料版本(version)記錄機制實現。即為資料增加乙個版本標識,在基於資料庫表的版本解決方案中,一般是通過為資料庫表增加乙個「version」欄位來實現。讀取出資料時,將此版本號一同讀出,之後更新時,對此版本號加一。此時,將提交資料的版本資料與資料庫表對應記錄的當前版本資訊進行比對,如果提交的資料版本號大於資料庫表當前版本號,則予以更新,否則認為是過期資料。樂觀鎖機制避免了長事務中的資料庫加鎖開銷(使用者a和使用者b操作過程中,都沒有對資料庫資料加鎖),大大提公升了大併發量下的系統整體效能表現。hibernate 在其資料訪問引擎中內建了樂觀鎖實現。需要注意的是,由於樂觀鎖機制是在我們的系統中實現,來自外部系統的使用者更新操作不受我們系統的控制,因此可能會造成髒資料被更新到資料庫中。

3、使用悲觀鎖進行控制。悲觀鎖大多數情況下依靠資料庫的鎖機制實現,如oracle的select … for update語句,以保證操作最大程度的獨占性。但隨之而來的就是資料庫效能的大量開銷,特別是對長事務而言,這樣的開銷往往無法承受。如乙個金融系統,當某個操作員讀取使用者的資料,並在讀出的使用者資料的基礎上進行修改時(如更改使用者賬戶餘額),如果採用悲觀鎖機制,也就意味著整個操作過程中(從操作員讀出資料、開始修改直至提交修改結果的全過程,甚至還包括操作員中途去煮咖啡的時間),資料庫記錄始終處於加鎖狀態,可以想見,如果面對成百上千個併發,這樣的情況將導致災難性的後果。所以,採用悲觀鎖進行控制時一定要考慮清楚。

死鎖的第三種情況

如果在事務中執行了一條不滿足條件的update語句,則執行全表掃瞄,把行級鎖上公升為表級鎖,多個這樣的事務執行後,就很容易產生死鎖和阻塞。類似的情況還有當表中的資料量非常龐大而索引建的過少或不合適的時候,使得經常發生全表掃瞄,最終應用系統會越來越慢,最終發生阻塞或死鎖。

解決方法:

sql語句中不要使用太複雜的關聯多表的查詢;使用「執行計畫」對sql語句進行分析,對於有全表掃瞄的sql語句,建立相應的索引進行優化。

5.小結

總體上來說,產生記憶體溢位與鎖表都是由於**寫的不好造成的,因此提高**的質量是最根本的解決辦法。有的人認為先把功能實現,有bug時再在測試階段進行修正,這種想法是錯誤的。正如一件產品的質量是在生產製造的過程中決定的,而不是質量檢測時決定的,軟體的質量在設計與編碼階段就已經決定了,測試只是對軟體質量的乙個驗證,因為測試不可能找出軟體中所有的bug。

Mysql資料庫鎖 表級鎖分析

按操作的型別分 讀鎖 共享鎖 針對同乙份資料,多個讀操作可以同時進行而不會相互影響。寫鎖 排它鎖 當前寫操作沒有完成,會阻斷其它的寫鎖和讀鎖。按對資料操作的粒度分 表鎖 偏讀 整個表被鎖,偏向於myisam引擎,開銷小,加鎖快,無死鎖 鎖定粒度大,發生鎖衝突的概率最高,併發度最低。行鎖 表級鎖分析 ...

資料庫 鎖分析

mysql 中提供了兩種封鎖粒度 行級鎖以及表級鎖。應該盡量只鎖定需要修改的那部分資料,而不是所有的資源。鎖定的資料量越少,發生鎖爭用的可能就越小,系統的併發程度就越高。但是加鎖需要消耗資源,鎖的各種操作 包括獲取鎖 釋放鎖 以及檢查鎖狀態 都會增加系統開銷。因此封鎖粒度越小,系統開銷就越大。在選擇...

資料庫鎖表

新增角色資訊,操作了角色表和角色許可權表。角色表進行了查詢操作。角色許可權表進行了新增許可權的操作。新增角色資訊的時候,需要新增角色表,對角色表進行了新增操作。需要對角色許可權表進行新增操作。綜上所述,對角色表進行查詢的時候,不能夠對角色表進行新增操作。對角色許可權白哦進行新增的時候,不能夠對角色許...