1、原理
MySQL默認的隔離級別是可重復讀,即:事務A在讀到一條數據之后,此時事務B對該數據進行了修改並提交,那么事務A再讀該數據,讀到的還是原來的內容。 那么MySQL可重復讀是如何實現的呢?使用的的一種叫MVCC的控制方式 ,即Mutil-Version Concurrency Control,多版本並發控制,類似於樂觀鎖的一種實現方式
實現方式:
InnoDB在每行記錄后面保存兩個隱藏的列來,分別保存了這個行的創建時間和行的刪除時間。這里存儲的並不是實際的時間值,而是系統版本號,當數據被修改時,版本號加1
在讀取事務開始時,系統會給當前讀事務一個版本號,事務會讀取版本號<=當前版本號的數據
此時如果其他寫事務修改了這條數據,那么這條數據的版本號就會加1,從而比當前讀事務的版本號高,讀事務自然而然的就讀不到更新后的數據了
2、增刪改查
假設初始版本號為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 | 2 | 3 |