資料庫 鎖以及死鎖的處理

2022-05-02 13:39:09 字數 2230 閱讀 3663

鎖分類:

參見:

acid(原子性,一致性,隔離性,永續性)四特性,事務是恢復和併發控制的基本單位。

1.樂觀鎖

樂觀鎖認為乙個使用者讀資料的時候,別人不會去寫自己所讀的資料,所以不做控制。樂觀鎖是基於系統儲存邏輯,限制較大,可能會引起髒讀等情況,得根據實際情況靈活運用(在儲存過程,函式使用)。

2.悲觀鎖

悲觀鎖就剛好相反,覺得自己讀資料庫的時候,別人可能剛好在寫自己剛讀的資料。所以在讀取資料的時候,為了不讓別人修改自己讀取的資料,就會先對自己讀取的資料加鎖,只有自己把資料讀完事務提交了,才允許別人修改那部分資料。

悲觀鎖可分為共享鎖(讀鎖)和排它鎖(寫鎖),預設來說,當sql指令碼修改更新某條記錄的時候,會給該條記錄加排他鎖,讀的話加的是共享鎖。

3.時間戳

時間戳就是不加鎖,通過時間戳來控制併發出現的問題。時間戳就是在資料庫表中單獨加一列時間字段,每次讀出來的時候,把該字段也讀出來,當寫回去的時候,把該字段加1,提交之前 ,跟資料庫的該字段比較一次,如果比資料庫的值大的話,就允許儲存,否則不允許儲存,這種處理方法雖然不使用資料庫系統提供的鎖機制,但是這種方法可以大大提高資料庫處理的併發量,因為這種方法可以避免了長事務中的資料庫加鎖開銷(操作員a 和操作員b操作過程中,都沒有對資料庫資料加鎖),大大提公升了大併發量下的系 統整體效能表現。但是操作員操作過程中可能會出現資料提交不了的情況,實際業務中限制較大。

死鎖在作業系統中指的是兩個或兩個以上的程序在執行的過程中,因爭奪資源而造成的一種互相等待的現象,若無外力作用,它們都將無法推進下去。此時稱系統處於死鎖狀態或者系統產生了死鎖,這些永遠在互相等待的程序稱為死鎖程序。

1. 事務之間對資源訪問順序的交替

出現原因: 

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

解決方法: 

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

2. 併發修改同一記錄

出現原因:主要是由於沒有一次性申請夠許可權的鎖導致的。參考:記錄一次死鎖排查過程

使用者a查詢一條紀錄,然後修改該條紀錄;這時使用者b修改該條紀錄,這時使用者a的事務裡鎖的性質由查詢的共享鎖企圖上公升到獨佔鎖,而使用者b裡的獨佔鎖由於a有共享鎖存在所以必須等a釋放掉共享鎖,而a由於b的獨佔鎖而無法上公升的獨佔鎖也就不可能釋放共享鎖,於是出現了死鎖。這種死鎖比較隱蔽,但在稍大點的專案中經常發生。 

解決方法:

a. 樂觀鎖,實現寫-寫併發

b. 悲觀鎖:使用悲觀鎖進行控制。悲觀鎖大多數情況下依靠資料庫的鎖機制實現,如oracle的select … for update語句,以保證操作最大程度的獨占性。但隨之而來的就是資料庫效能的大量開銷,特別是對長事務而言,這樣的開銷往往無法承受。

3. 索引不當導致的死鎖

出現原因: 

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

另外一種情況是由於二級索引的存在,上鎖的順序不同導致的,這部分在討論索引時會提到。參考:

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

那麼,如何盡可能的避免死鎖呢?

1)以固定的順序訪問表和行。即按順序申請鎖,這樣就不會造成互相等待的場面。

2)大事務拆小。大事務更傾向於死鎖,如果業務允許,將大事務拆小。

3)在同乙個事務中,盡可能做到一次鎖定所需要的所有資源,減少死鎖概率。

4)降低隔離級別。如果業務允許,將隔離級別調低也是較好的選擇,比如將隔離級別從rr調整為rc,可以避免掉很多因為gap鎖造成的死鎖。

5)為表新增合理的索引。如果不走索引將會為表的每一行記錄新增上鎖,死鎖的概率大大增大。

資料庫死鎖處理

查詢 select ses.sid as sid,ses.serial as serial num,ses.process as process,ses.username as db username,pro.spid as host pid,ses.machine as machine,subst...

資料庫索引 鎖 死鎖

平衡多路查詢樹 樹的左右兩邊的層級數相差不會大於1 非葉子節值大於左邊子節點 小於右邊子節點!mysql索引存在硬碟上 b 樹子節點才存資料 非葉結點僅具有索引作用 且是有序的 範圍查詢 層級也不高,減少io b樹不管葉子節點還是非葉子節點,都會儲存資料,這樣導致在非葉子節點中能儲存的指標數量變少 ...

資料庫系列 資料庫事務 鎖 死鎖

保障資料庫事務的鎖 非鎖 死鎖 資料庫事務級別 事務級別的使用 注意事項 髒讀 不可重複讀 幻讀 不可重複讀 幻讀 事務的實現原理 寫鎖 讀寫鎖的公升級關係 也是產生死鎖的原因 共享鎖 獨佔鎖 意向共享鎖 事務在給乙個資料行加共享鎖前必須先取得該錶的is鎖。意向排他鎖 事務在給乙個資料行加排他鎖前必...