MySQL 事務隔離級別

MySQL 事務隔離級別

前言

簡單來講,數據庫事務就是保證一組數據操做要麼所有成功,要麼所有失敗。在 MySQL 中,事務是在引擎層實現的。原生的 MyISAM 引擎不支持事務,也是爲何 InnoDB 會取代它的重要緣由之一。數據庫

隔離性與隔離級別

當數據庫上有多個事務同時執行的時候,根據隔離級別的不一樣,可能會出現髒讀、幻讀和不可重複讀。標準隔離級別包括讀未提交、讀提交、可重複讀和串行化。segmentfault

讀未提交

若是用這種隔離級別,事務執行的時候會讀到其餘未提交事務的數據,咱們稱爲髒讀。ide

客戶端A
start transaction;
update users set name = 'hello' where id = 1;
select * from users where id = 1; #此時能夠讀到 name,更新爲hello
客戶端B
start transaction;
select * from users where id = 1; #此時讀到 name爲hello

在此隔離級別下,客戶端 B 讀到了客戶端 A 還未提交的事務即還未 commit 的事務,即產生的髒讀現象。code

讀提交

若是用這種隔離級別,事務執行的時候會讀到其餘已提交事務的數據,咱們稱爲不可重複讀。blog

客戶端A
start transaction;
update users set name = 'hello' where id = 1;
commit;
客戶端B
start transaction;
select * from users where id = 1; #此時 name不爲hello
#此時客戶端A 完成 commit
select * from users where id = 1; #此時 name爲hello

在此隔離級別下,客戶端 B 讀到了客戶端 A 完成提交的事務,產生了不可重複讀現象。事務

可重複讀

在同一個事務裏,SELECT 語句得到的結果是基於事務開始時間點的狀態,同一個事務中 SELECT 語句獲得的結果是同樣的,可是會有幻讀現象。get

客戶端A
start transaction;
select * from users;  #爲空
#此時客戶端B 完成commit 操做
select * from users;  #仍是爲空
insert into users(id, name) value (1, 'hello') #報主鍵衝突
客戶端B
start transaction;
select * from users; #爲空
insert into users(id, name) values (1, 'hello');
commit;

在此隔離級別下,會產生幻讀現象。it

串行化

在該事務級別下,事務都是串行順序執行的,避免了髒讀,不可重複讀,幻讀問題。io

客戶端A
start transaction;
insert into users(id, name) values (1, 'hello');
commit;
客戶端B
start transaction;
select * from users; #會一直堵塞住,直到客戶端A 完成提交

原文連接:https://segmentfault.com/a/1190000023085634class

相關文章
相關標籤/搜索