- 未提交讀(髒讀)
- 已提交讀
- 可重複讀
- 可串行化
未提交讀,兩個事務之間的每個操作都會影響。當A事務改一個表,在A事務提交前,B事務是可以查詢到這個修改的。
已提交讀,A事務做出的修改,提交前B事務是不可見的。但是提交了,B事務就可以查詢到這個修改了。所以當A事務沒提交前,B查詢到的結果和A事務提交後B查詢的結果是不一致的。這就是不可重複讀。
可重複讀,可重複讀解決了上面的問題,我自己做了些實驗,自己總結的一些猜想來說明可重複讀。在可重複讀的隔離級別,每個事務查詢的時候,都會爲自己複製一份數據,每次查詢的時候就查自己的這份複製。這樣就不會有不可重複讀的問題,因爲每個事務都有自己複製的數據。但是在可重複讀的隔離級別,還會有幻讀的問題。幻讀的定義,感覺網上的說得不清不楚。首先確定一點,在可重複讀隔離級別,一個事務修改了一個表,另一個事務是不能再操作這張表的。實驗的時候,我發現我修改了一張表,另一個事務操作的時候就一直卡在那。所以可重複讀是會鎖表的。當A事務添加了一條數據,記住要提交不然B不能修改,B事務去update的時候,會發現多了這條數據。還有其他”奇怪”的現象,總之就是我們操作的數據不是隔離的。做了幾次實驗後,我覺得原理應該是這樣的。當A事務做出修改後,A事務的數據會和B事務原來的數據整合,B修改的數據不是原來複制的數據了。其實是和A事務整合的數據。所以我們以修改複製的數據去想它修改後的結果肯定是不對的。還是用例子來說吧
tableA
id | version |
---|---|
1 | 1.1 |
2 | 1.2 |
3 | 1.3 |
A事務
insert into table value('4','1.4');
update table set version='2' where id='2';
commit;
B事務
update table set version = '1' where id='1'
select * from table
tableB
id | version |
---|---|
1 | 1 |
2 | 2 |
3 | 1.3 |
4 | 1.4 |
tableC
id | version |
---|---|
1 | 1.1 |
2 | 2 |
3 | 1.3 |
4 | 1.4 |
其實A事務修改的不是tableA,而是tableC,tableC就是上面所說的整合的結果。
可串行化
解決了幻讀的問題
下面是mysql 查詢隔離級別的命令:
select @@global.tx_isolation ,@@Session.tx_isolation
兩個字段分別是全局和當前會話的隔離級別
設置當前會話隔離級別:
set session transaction isolation level read committed
set session transaction isolation level read uncommitted
set session transaction isolation level repeatable read