一致性非鎖定讀(consistent nonlocking read) 一致性非鎖定讀是值InnoDB存儲引擎通過多版本控制(multi versioning)的方式來讀取當前執行時間資料庫中的數據。如果被讀的數據行被加了排他鎖,在讀取這行數據的時候並不會等待鎖釋放,而是讀取該行的一個快照數據。 之 ...
一致性非鎖定讀(consistent nonlocking read)
一致性非鎖定讀是值InnoDB存儲引擎通過多版本控制(multi versioning)的方式來讀取當前執行時間資料庫中的數據。如果被讀的數據行被加了排他鎖,在讀取這行數據的時候並不會等待鎖釋放,而是讀取該行的一個快照數據。
之所以稱為非鎖定讀,因為不需要等待被訪問行的X鎖的釋放。快照數據是指改行之前的數據版本,該實現通過undo段來完成。
非鎖定讀的方式極大提高了資料庫的併發性。在InnoDB存儲引擎中,這是預設的讀取方式。
快照數據其實就是當前行數據的一個歷史版本,每行記錄可能有多個版本。這種技術成為行多版本技術。由此帶來的併發控制,成為多版本併發控制(Multi Version Concurrency Control,MVCC)。
在事務的隔離級別,READ COMMITED和REPEATABLE READ下,對快照數據的定義不同。在READ COMMITTED事務隔離級別下,對於快照數據,非一致性讀總是讀取被鎖定行的最新一份快照數據。而在REPEATABLE READ事務隔離級別下,對於快照數據,非一致性讀總是讀取事務開始時的數據版本。
也就是說在READ COMMITTED事務隔離級別下,非鎖定讀讀取到的數據是最新的快照版本數據,也就是可以讀到另一個事務已經提交了的快照數據。而在REPEATABLE READ下,只會讀到事務開始前的數據。
一致性鎖定讀
在預設情況下,InnoDB存儲引擎對數據採用的是一致性非鎖定讀。但是有些情況下為了保證數據邏輯的一致性,需要對SELECT的操作加鎖。InnoDB存儲引擎對於SELECT語句支持兩種一致性的鎖定讀(locking read)操作。
1、 SELECT …… FOR UPDATE
2、 SELECT …… LOCK IN SHARE MODE
其中,SELECT …… FOR UPDATE對讀取的記錄加一個X鎖,其他事務不能對已鎖定的行加任何鎖。而SELECT …… LOCK IN SHARE MODE是對讀取的記錄加一個S鎖。
即使被讀取的行被加了一致性鎖定讀,如果有另一個一致性非鎖定讀的操作來讀取該行數據是不會阻塞的,讀取的是改行的快照版本。
SELECT …… FOR UPDATE和SELECT …… LOCK IN SHARE MODE必須在一個事務中,當一個事務提交了,鎖就釋放了。因此在使用上述兩個SELECT鎖定語句時,必須開啟事務。
外鍵鎖
對於外鍵值的插入和更新,首先需要查找父表中的記錄,即SELECT父表。但是對於父表的SELECT操作,不是採用一致性非鎖定讀的方式,因為這樣可能會發生數據不一致的問題。此時採用過的是SELECT …… LOCK IN SHARE MODE的方式,給父表的記錄加一個S鎖。如果此時對父表加一個X鎖,則會被阻塞。