天天看點

MySQL可重複讀隔離級别的實作原理

原理

MySQL預設的隔離級别是可重複讀,即:事務A在讀到一條資料之後,此時事務B對該資料進行了修改并送出,那麼事務A再讀該資料,讀到的還是原來的内容。 那麼MySQL可重複讀是如何實作的呢?

使用的的一種叫MVCC的控制方式 ,即Mutil-Version Concurrency Control,多版本并發控制,類似于樂觀鎖的一種實作方式

實作方式

InnoDB在每行記錄後面儲存兩個隐藏的列來,分别儲存了這個行的建立時間和行的删除時間。這裡存儲的并不是實際的時間值,而是系統版本号,當資料被修改時,版本号加1

在讀取事務開始時,系統會給目前讀事務一個版本号,事務會讀取版本号<=目前版本号的資料

此時如果其他寫事務修改了這條資料,那麼這條資料的版本号就會加1,進而比目前讀事務的版本号高,讀事務自然而然的就讀不到更新後的資料了

增删改查

假設初始版本号為1:

INSERT

insert into user (id,name) values (1,'Tom');

id name create_version delete_version
1 Tom 1

下面模拟一下文章開頭的場景:

SELECT (事務A)

select * from user where id = 1;

此時讀到的版本号為1

UPDATE(事務B)

update user set name = 'Jerry' where id = 1;

在更新操作的時候,該事務的版本号在原來的基礎上加1,是以版本号為2。

先将要更新的這條資料标記為已删除,并且删除的版本号是目前事務的版本号,然後插入一行新的記錄

id name create_version delete_version
1 Tom 1 2
1 Jerry 2

SELECT (事務A)

此時事務A再重新讀資料:

select * from user where id = 1;

由于事務A一直沒送出,是以此時讀到的版本号還是為1,是以讀到的還是Tom這條資料,也就是可重複讀

DELETE

delete from user where id = 1;

在删除操作的時候,該事務的版本号在原來的基礎上加1,是以版本号為3

删除時,将目前版本号作為删除版本号

id name create_version delete_version
1 Jerry