MySQL 事務與鎖詳解

2021-08-31 13:35:33 字數 1588 閱讀 2913

一系列的資料庫操作,這些操作必須全部執行,否則全部不執行。例如一些和銀行賬戶訪問相關的資料庫操作,必須得保證每乙個操作得執行。

由於為了加快資料庫的操作,需要資料庫支援併發,這樣就可能會產生多個事務同時操作同一張表,這樣就可能產生一些衝突。如下:

既然存在這些衝突,於是下面引出事務的隔離級別概念,他們就是用來解決這些衝突的方案。

read uncommitted(未提交讀)

事務中的修改,即使沒有提交,其他事務也可以看得到,會導致「髒讀」、「幻讀」和「不可重複讀取」。

read commited (提交讀)

大多數主流資料庫的預設事務等級,保證了乙個事務不會讀到另乙個並行事務已修改但未提交的資料。其實質上是對進行修改但未提交的的資料加了鎖,這樣就避免了事務回滾帶來的贓讀可能

但不能避免「幻讀」和「不可重複讀取」,因為該級別只是對修改操作的資料加了鎖,並未對讀取操作的資料加鎖。不能避免其他事務對這些已讀取的資料進行修改

repeatable read(重複讀)

保證了乙個事務不會修改已經由另乙個事務讀取但未提交(回滾)的資料。其實質上,就是對已讀取但未提交的資料加了鎖,這樣就避免了其他事務對這些資料進行修改,避免了「髒讀取」和「不可重複讀取」的情況。

但不能避免「幻讀」,因為幻讀是對非讀取的資料進行操作,而這一級別的隔離是對已讀取和已操作的資料進行限制。mysql預設事務隔離級別serializable (序列化)

最嚴格的級別,事務序列執行,資源消耗最大。最嚴格的級別,事務序列執行,資源消耗最大。每乙個事務進行操作時,都對錶進行加鎖,不允許其他事務進行操作。

後來為了解決幻讀,引入了mvcc(多版本併發控制)機制。下面簡單介紹一下:

其實質上是通過對錶增加乙個版本欄位來實現的。比如innodb中的實現機制,它通過對每個表增添版本起始字段(建立時的版本號刪除時的版本號)來進行版本控制。每開始乙個新的事務,系統版本號都會自動遞增。事務開始時刻的系統版本號會作為事務的版本號。

innodb會根據以下兩個條件檢查每行記錄:

innodb只查詢版本早於當前事務版本的資料行(也就是,行的系統版本號小於或等於事務的系統版本號),這樣可以確保事務讀取的行,要麼是在事務開始前已經存在的,要麼是事務自身插入或者修改過的。

行的刪除版本要麼未定義,要麼大於當前事務版本號。這可以確保事務讀取到的行,在事務開始之前未被刪除。

從上面事務的相關概念,可以發現,要想實現事務的隔離級別,也可以說是為了解決併發衝突,我們必須得依靠鎖。鎖是一種實現事務隔離級別和併發的一種機制。

根據處理策略的不同,在不同的角度便有不同的鎖分類:

功能:共享鎖(讀鎖)、排它鎖(寫鎖)

粒度:表鎖、行鎖

我們可以發現mvcc實際上就是一種樂觀鎖機制,它就是在提交前檢查版本號是否滿足條件。但並不是任何場景都適合樂觀鎖機制

比如update、insert、delete非常頻繁的場景下,樂觀鎖機制就不適合,因為這樣會造成大量的事務回滾操作,大量浪費時間。

相反在查詢操作比例大於增刪改操作時,就適合用樂觀鎖機制。

mysql事務與鎖機制 mysql事務與鎖機制

在併發下事務會容易出現的一些問題 資料更新丟失 兩個事務同時操作一條資料,乙個事務因為異常導致資料更新丟失 髒讀 乙個失誤開始讀取了某行資料,另外乙個事務已經更新了此資料但沒有能夠及時提交。這是相當危險的,因為很可能所有的操作都被回滾。不可重複讀 乙個事務對同一行資料重複讀取兩次,但是卻得到了不同的...

MYSQL 事務與鎖

事務的特性 acid 原子性一致性 隔離性永續性 通過redolog 和 doublewrite 頁損壞的情況 實現永續性 事務什麼時候開啟 預設自動開啟,自動提交。通過begin 命令顯式開啟事務 通過commit rollback 結束事務。事務的隔離級別 讀未提交 存在的問題 髒讀 不可重複讀...

mysql鎖與事務總結

未提交讀,乙個事務查詢到另乙個事務未提交資料 髒讀 提交讀,乙個事務中兩次查詢可能查出不同資料 不可重複讀 可重複讀,乙個事務中每次查詢到的資料集相同 幻讀 串性化mysql資料引擎innodb,支援事務,預設使用行鎖,行鎖開銷大但粒度小,併發處理能力高。當執行insert update delet...