mysql的並發控制


並發即指在同一時刻,多個操作並行執行。MySQL對並發的處理主要應用了兩種機制——是"鎖"和"多版本控制"。

1、並發控制

MySQL提供兩個級別的並發控制:服務器級(the server level)和存儲引擎級(the storage engine level)。加鎖是實現並發控制的基本方法,MySQL中鎖的粒度:

(1) 表級鎖:MySQL獨立於存儲引擎提供表鎖,例如,對於ALTER TABLE語句,服務器提供表鎖(table-level lock)。

(2) 行級鎖:InnoDB和Falcon存儲引擎提供行級鎖,此外,BDB支持頁級鎖。

另外,值得一提的是,MySQL的一些存儲引擎(如InnoDB、BDB)除了使用封鎖機制外,還同時結合MVCC機制,即多版本並發控制(Multi-Version Concurrent Control),來實現事務的並發控制,從而使得只讀事務不用等待鎖,提高了事務的並發性。

鎖的分類

共享鎖:也稱為讀鎖,讀鎖允許多個連接可以同一時刻並發的讀取同一資源,互不干擾;
排他鎖:也稱為寫鎖,一個寫鎖會阻塞其他的寫鎖或讀鎖,保證同一時刻只有一個連接可以寫入數據,同時防止其他用戶對這個數據的讀寫。

 

2、事務處理

2.1 事務的ACID特性

數據庫的事務處理的原則是保證ACID的正確性。

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

(1) 原子性(Atomicity):事務是一個原子操作單元,其對數據的修改,要么全都執行,要么全都不執行,不可能只執行其中的一部分。(不可分割)

(2) 一致性(Consistent):在事務開始和完成時,數據都必須保持一致狀態。這意味着所有相關的數據規則都必須應用於事務的修改,以保持數據的完整性;事務結束時,所有的內部數據結構(如B樹索引或雙向鏈表)也都必須是正確的。(狀態更改一致性)

(3) 隔離性(Isolation):數據庫系統提供一定的隔離機制,保證事務在不受外部並發操作影響的“獨立”環境執行。這意味着事務處理過程中的中間狀態對外部是不可見的。(執行過程隔離不可見)

(4) 持久性(Durable):事務完成之后,它對於數據的修改是永久性的,即使出現系統故障也能夠保持。(持久生效)

2.2 事務處理帶來的問題

由於事務的並發執行,帶來以下一些著名的問題:

(1) 更新丟失(Lost Update):當兩個或多個事務選擇同一行,然后基於最初選定的值更新該行時,由於每個事務都不知道其他事務的存在,就會發生丟失更新問題--最后的更新覆蓋了由其他事務所做的更新。

(2) 臟讀(Dirty Reads):一個事務正在對一條記錄做修改,在這個事務完成並提交前,這條記錄的數據就處於不一致狀態;這時,另一個事務也來讀取同一條記錄,如果不加控制,第二個事務讀取了這些"臟"數據,並據此做進一步的處理,就會產生未提交的數據依賴關系。這種現象被形象地叫做"臟讀"。

(3) 不可重復讀(Non-Repeatable Reads):一個事務在讀取某些數據后的某個時間,再次讀取以前讀過的數據,卻發現其讀出的數據已經發生了改變、或某些記錄已經被刪除了!這種現象就叫做"不可重復讀"。

(4) 幻讀(Phantom Reads):一個事務按相同的查詢條件重新讀取以前檢索過的數據,卻發現其他事務插入了滿足其查詢條件的新數據,這種現象就稱為"幻讀"。

2.3 Mysql隔離級別

READ UNCOMMITTED :事務可以看到其他事務沒有被提交的數據(臟數據)。
READ COMMITTED :事務可以看到其他事務已經提交的數據。
REPEATABLE READ :保證事務中多次查詢的結果相同(Innodb默認級別),會出現幻讀。
SERIALIZABLE :所有事務順序執行,對所有read操作加鎖。保證一致性。

 

3、多版本並發控制 

MVCC的實現:通過保存數據資源在不同時間點的快照實現的。根據事務開始的時間不同,每個事務看到的數據快照版本是不一樣的。

InnoDB中的MVCC實現:通過在每行記錄后面保存兩個隱藏的列來實現,一個保存了行的創建時間,一個保存了行的過期時間。

SELECT

當讀取記錄時,存儲引擎會選取滿足下面兩個條件的行作為讀取結果。

讀取記錄行的開始版本號必須早於當前事務的版本號。也就是說,在當前事務開始之前,這條記錄已經存在。在事務開始之后才插入的行,事務不會看到。

讀取記錄行的過期版本號必須晚於當前事務的版本號。也就是說,當前事務開始的時候,這條記錄還沒有過期。在事務開始之前就已經過期的數據行,該事務也不會看到。

INSERT

存儲引擎為新插入的每一行保存當前的系統版本號作為這一行的開始版本號。

UPDATE

存儲引擎會新插入一行記錄,當前的系統版本號就是新記錄行的開始版本號。同時會將原來行的過期版本號設為當前的系統版本號。

DELETE

存儲引擎將刪除的記錄行的過期版本號設置為當前的系統版本號。

MVCC只在 REPEATABLE READ 和 READ COMMITTED 兩個隔離級別下工作。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM