天天看點

mysql事務的隔離級别

mysql事務的隔離級别

1.隔離等級産生的問題

髒讀(Drity Read):A,B兩個事務同時操作表C,A事務修改C表但是未送出,但是此時B事務查詢會擷取到A事務修改後的資料。

不可重複讀(Non-repeatable read):A,B兩個事務同時操作表C成績字段,A事務第一次查詢成績為80(A事務未結束),B事務修改成績為90分,此時A事務再次查詢成績就為90分。兩次查詢結果不同。

幻讀(Phantom Read):A,B兩個事務操作C表,A查詢id為100分的資料,得到null,此時B插入一條id為100資料,送出,A再次插入id為100的資料發現資料已經存在,A懵逼了,剛才我還沒有查到為什麼不能插入。。。。。。

2.事務的隔離等級

未送出讀(Read Uncommitted):允許髒讀,也就是可能讀取到其他會話中未送出事務修改的資料。

送出讀(Read Committed):隻能讀取到已經送出的資料。

可重複讀(Repeated Read):可重複讀。在同一個事務内的查詢都是事務開始時刻一緻的,InnoDB預設級别。在SQL标準中,該隔離級别消除了不可重複讀,但是還存在幻讀。

串行化(Serializable):完全串行化的讀,每次讀都需要獲得表級共享鎖,讀寫互相都會阻塞,效率最低,可以避免髒讀,幻讀,不可重複讀。

這四種隔離等級從上向下依次變低

髒讀 不可重複讀 幻讀
未送出讀
送出讀 ×
可重複讀
串行化

3.避免幻讀的方法

在第一次查詢之後,手動加入鎖,不允許别人插入id為100的資料。

SELECT id FROM C WHERE id = 100 FOR UPDATE;      

4.資料庫預設的隔離等級

mysql預設的隔離等級 可重複讀。

oracle,SQL Server預設為 送出讀。

5.查詢mysql目前隔離等級

1. 1.查詢目前會話和全局會話等級
2. SELECT @@global.tx_isolation, @@tx_isolation;
3. 
4. 2.設定目前會話隔離級别
5. 
6. set session transaction isolatin level (read uncommitted,read committed,repeatable read,serializable);
7. 
8. 3.設定系統目前隔離級别
9. 
10. set global transaction isolation level (read uncommitted,read committed,repeatable read,serializable);