1. 程式人生 > 實用技巧 >mysql innodb 儲存引擎的事務隔離級別

mysql innodb 儲存引擎的事務隔離級別

事務隔離級別

read uncommitted(未提交讀),導致髒讀。
read committed(提交度),導致不可重複讀。
repeatable read(可重複讀),導致幻讀。
serializable(序列化), 效率過低。

我們的隔離級別都是針對多個事務操作同一資料來定義的,比如未提交讀,那就是當前事務設定未提交讀,那麼其他事務在事務中未commit的資料當前事務可以讀取。

預設的事務隔離級別是 repeatable read

mysql> show variables like '%isolation%' ;
+-----------------------+-----------------+
| Variable_name         | Value           |
+-----------------------+-----------------+
| transaction_isolation | REPEATABLE-READ |
| tx_isolation          | REPEATABLE-READ |
+-----------------------+-----------------+

表結構

create table

create table student(
 id int primary key,
 name varchar(255)

);
insert into student values(1,'student1');

select * from student;

read uncommitted(未提交讀)

事務A

set session transaction isolation level read uncommitted;
start transaction;
select * from student;

事務B

set session transaction isolation level read uncommitted;
set session transaction isolation level read committed;
set session transaction isolation level repeatable read;
set session transaction isolation level serializable;

start transaction;
update student set name ='student2' where id = 1;
select *  from student ;
rollback;

只要事務A的隔離級別為 read uncommitted,事務B的隔離級別為任意級別,A都會髒讀。

serializable(序列化)

事務B阻塞

事務A 後執行

set session transaction isolation level serializable;
start transaction;
select * from student;

事務B 後執行

update student set name ='student2' where id = 1;  --將會阻塞

事務A阻塞

事務B 後執行

start transaction;
update student set name ='student2' where id = 1;  

事務A 後執行

set session transaction isolation level serializable;
start transaction;
select * from student; --將會阻塞

總結

事務 A B 事務A sql執行結果
隔離級別 read uncommitted 任意 A讀取出B事務中未提交的資料
隔離級別 read uncommitted 任意 A沒有讀出B事務中未提交的資料
隔離級別 repeatable read 任意 A沒有讀出B事務中未提交的資料,並且在A開啟事務後查詢,無論B事務是否提交,讀取的結果都是一致的。
隔離級別 serializable 任意 A沒有讀取B事務中未提交的資料,並且在A開啟事務查詢後, B事務的更新相關資料會阻塞。B事務開啟事務後並更新資料,A讀取相關資料會阻塞。

read uncommitted ,read uncommitted 都是讀取資料,其他事務的操作級別對其讀取不會造成阻塞。
serializable 可能由於其他事務更新資料,導致當前讀取,更新相關資料 阻塞。