MySQL中的鎖

事務及其ACID屬性:

事務是由一組sql語句組成的邏輯處理單元,具有4個屬性

原子性:事務是一個原子操作單元,其對數(shù)據(jù)的修改,要么都執(zhí)行,要么都不執(zhí)行

一致性:事務開始和完成的時候,數(shù)據(jù)都必須保持一致。事物的修改必須保持數(shù)據(jù)的完整性,事務結束后所有的內部數(shù)據(jù)結構(B+樹,雙向鏈表)多必須是正確的

隔離性:數(shù)據(jù)庫系統(tǒng)提供一定的隔離機制,保證事務在不受外界并發(fā)操作影響的環(huán)境中執(zhí)行。意味著事務處理過程中的中間狀態(tài)對外部是不可見的

持久性:事務完成之后,對數(shù)據(jù)的修改是永久性的


并發(fā)事務處理帶來的問題:

更新丟失:兩個或多個事務同時選擇一行并更新該行的數(shù)據(jù),最后的更新覆蓋了由其他事務做的更新。

臟讀:一個事務正在對一條記錄進行修改,在這個事務提交之前,其他事務過來了讀取了臟數(shù)據(jù)并進一步做了處理,就會產生未提交的數(shù)據(jù)依賴關系。??

不可重復讀:一個數(shù)據(jù)在讀取某些數(shù)據(jù)后的某個時間,再次讀取以前讀過的數(shù)據(jù),會發(fā)現(xiàn)其讀出的數(shù)據(jù)發(fā)生了變化或者被刪除

幻讀:一個事務按相同的查詢條件重新讀取以前檢索過的數(shù)據(jù),發(fā)現(xiàn)其他事務插入了滿足其查詢條件的新數(shù)據(jù)


事務隔離級別:

更新丟失問題通常是應該完全避免的,并不能只靠數(shù)據(jù)庫的事務控制器解決,需要應用程序對要更新的數(shù)據(jù)加必要的鎖來解決,防止更新丟失是應用的責任

臟讀,不可重復讀,幻讀屬于數(shù)據(jù)庫讀一致性問題,必須由數(shù)據(jù)庫提供一定的事務隔離機制解決

1.? ? 在讀取數(shù)據(jù)前加鎖

2.不加鎖,通過數(shù)據(jù)多版本并發(fā)控制

四種事務隔離級別:




表鎖:開銷小,加鎖快,不會出現(xiàn)死鎖,并發(fā)度低,容易鎖沖突

行鎖:開銷大,加鎖慢,會出現(xiàn)死鎖,并發(fā)度高,不容易鎖沖突


InnoDB使用兩種類型的行鎖:

共享鎖S(鎖的是行):稱為讀鎖,就是說事務1對數(shù)據(jù)A加了S鎖,事務1只能讀不能修改A,其他事務也一樣只能讀不能寫,只能加S鎖不能加X鎖,除非事務1釋放S鎖

排他鎖X(du'de鎖的是行):稱為寫鎖,事務1對數(shù)據(jù)加了X鎖,能讀能寫,其他事務不能讀和寫,不能加任何鎖

意向共享鎖IS(鎖的是表):通知數(shù)據(jù)庫要加什么表并對表進行加鎖,如果需要對A進行加共享鎖,先對該表加意向共享鎖后再對A加共享鎖

意向排他鎖IX(鎖的是表):同上

意向共享鎖和意向排他鎖都是由數(shù)據(jù)庫加的

InnoDB行鎖是通過給索引加鎖來實現(xiàn)的,只有通過索引條件檢索數(shù)據(jù)才是使用行鎖,否則使用表鎖



間隙鎖:

當我們用范圍t條件而不是相等條件檢索數(shù)據(jù)時,并請求了共享鎖或者排他鎖,InnoDB會給符合條件的已有數(shù)據(jù)記錄的索引項加鎖,對于在范圍但是不存在的記錄,會加間隙鎖

目的:防止幻讀,滿足相關隔離級別的要求。因為有可能在讀的過程其他事務插入了新的數(shù)據(jù),就會產生幻讀。

但這會造成嚴重的鎖等待,因此要盡量使用相等條件來訪問更新數(shù)據(jù),避免使用范圍條件


什么時候使用表鎖:

對于InnoDB表,在絕大部分情況下都應該使用行級鎖,因為事務和行鎖往往是我們之所以選擇InnoDB表的理由。但在個別特殊事務中,也可以考慮使用表級鎖。

第一種情況是:事務需要更新大部分或全部數(shù)據(jù),表又比較大,如果使用默認的行鎖,不僅這個事務執(zhí)行效率低,而且可能造成其他事務長時間鎖等待和鎖沖突,這種情況下可以考慮使用表鎖來提高該事務的執(zhí)行速度。

第二種情況是:事務涉及多個表,比較復雜,很可能引起死鎖,造成大量事務回滾。這種情況也可以考慮一次性鎖定事務涉及的表,從而避免死鎖、減少數(shù)據(jù)庫因事務回滾帶來的開銷。

當然,應用中這兩種事務不能太多,否則,就應該考慮使用MyISAM表了。


避免死鎖的方法:

(1)在應用中,如果不同的程序會并發(fā)存取多個表,應盡量約定以相同的順序來訪問表,這樣可以大大降低產生死鎖的機會。

(2)在程序以批量方式處理數(shù)據(jù)的時候,如果事先對數(shù)據(jù)排序,保證每個線程按固定的順序來處理記錄,也可以大大降低出現(xiàn)死鎖的可能。

(3)在事務中,如果要更新記錄,應該直接申請足夠級別的鎖,即排他鎖,而不應先申請共享鎖,更新時再申請排他鎖,因為當用戶申請排他鎖時,其他事務可能又已經(jīng)獲得了相同記錄的共享鎖,從而造成鎖沖突,甚至死鎖。

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容