資料庫和作業系統一樣,是一個多使用者使用的共享資源。當多個使用者并發地存取資料 時,在資料庫中就會産生多個事務同時存取同一資料的情況。若對并發操作不加控制就可能會讀取和存儲不正确的資料,破壞資料庫的一緻性。加鎖是實作資料庫并 發控制的一個非常重要的技術。在實際應用中經常會遇到的與鎖相關的異常情況,當兩個事務需要一組有沖突的鎖,而不能将事務繼續下去的話,就會出現死鎖,嚴 重影響應用的正常執行。
在資料庫中有兩種基本的鎖類型:排它鎖(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。
版權聲明:本文為CSDN部落客「weixin_34315189」的原創文章,遵循CC 4.0 BY-SA版權協定,轉載請附上原文出處連結及本聲明。
原文連結:https://blog.csdn.net/weixin_34315189/article/details/92379005