mysql四種隔離級別


mysql 事務有四種隔離級別,分別是:讀未提交READ UNCOMMITTED 、讀提交 READ COMMITTED、可重復讀REPEATABLE READ、串行化SERIALIZABLE。下面我們分別看下不同隔離級別下對事務的影響。

首先查看mysql的隔離級別: 

show variables like 'transaction_isolation';

我們看到mysql的默認隔離級別是可重復讀,下面設置mysql的隔離級別為讀未提交。這里我們只設置當前會話的隔離級別: set session transaction isolation level READ UNCOMMITTED; 然后我們在數據庫中建立這樣一張表 staffs:
CREATE TABLE `staffs` (
  `id` int DEFAULT NULL,
  `name` char(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL,
  `age` int DEFAULT NULL,
  KEY `id_name_age_index` (`id`,`name`,`age`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci

然后預置一部分數據:

讀未提交

接下來我們進行一個操作,來演示讀未提交的隔離級別。

事務A執行:

BEGIN;
select * from staffs where id =1;

得到如下結果:

事務B執行:

BEGIN;
select * from staffs where id =1;
update staffs set age=11 where id=1;

事務B 執行完update操作后,在事務A中,再查詢下id=1的值,如下所示:

可以看到,此時事務A已經讀到了事務B的修改,注意此時事務B尚未提交commit。 這個也就是我們所說的臟讀。

讀已提交

接下來演示下讀提交,修改當前會話的隔離級別為READ COMMITTED讀提交

set session transaction isolation level READ COMMITTED;

然后按照上面的順序執行:

發現,在讀提交的隔離級別下,當事務B修改完數據尚未提交時,事務A是無法讀取到修改的數據的。當事務B提交事務后,事務A才可以看到修改的結果。

可重復讀

修改當前會話的隔離級別為可重復讀:

set session transaction isolation level REPEATABLE READ;

還按照上面的事務執行順序執行:

可以發現,當事務B提交后,事務A查詢的結果依然是事務A開啟時讀到的數據,這就是所謂的可重復讀,也就是說事務開啟時讀到的數據,在事務提交前,是一致的,不會因為外面事務的修改提交而改變開啟事務前讀到的值。

串行化

設置數據庫的隔離級別為SERIALIZABLE,然后按照圖下的步驟執行操作

當事務A 查詢id為1的數據行后,事務B嘗試去update id=1的數據行,就會被阻塞住。只有當事務Acommit 后,事務B才執行成功(可以看到步驟2執行了22秒)。當事務A再進行查詢ID=1的數據時,發現age還是13,而事務B查詢已經變成了14.這是因為事務B還沒有提交,對於串行化,對於同一行數據,必須一個事務一個事務順序執行,當事務B提交后,事務A再查詢,就變成了14.

 

鏈接:https://juejin.cn/post/7073668254727667726
來源:稀土掘金


免責聲明!

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



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