mysql事務隔離級別

2021-09-10 08:48:52 字數 2543 閱讀 8954

mysql預設的事務隔離級別為repeatable-read

1、讀未提交:

(1)開啟乙個客戶端a,並設定當前事務模式為read uncommitted(未提交讀),查詢表account的初始值:

(2)在客戶端a的事務提交之前,開啟另乙個客戶端b,更新表account:

(3)這時,雖然客戶端b的事務還沒提交,但是客戶端a就可以查詢到b已經更新的資料:

(4)一旦客戶端b的事務因為某種原因回滾,所有的操作都將會被撤銷,那客戶端a查詢到的資料其實就是髒資料:

(5)在客戶端a執行更新語句update account set balance = balance - 50 where id =1,lilei的balance沒有變成350,居然是400,是不是很奇怪,資料不一致啊,如果你這麼想就太天真 了,在應用程式中,我們會用400-50=350,並不知道其他會話回滾了,要想解決這個問題可以採用讀已提交的隔離級別

2、讀已提交

(1)開啟乙個客戶端a,並設定當前事務模式為read committed(不可重複讀),查詢表account的所有記錄:

(2)在客戶端a的事務提交之前,開啟另乙個客戶端b,更新表account:

(3)這時,客戶端b的事務還沒提交,客戶端a不能查詢到b已經更新的資料,解決了髒讀問題:

(4)客戶端b的事務提交

(5)客戶端a執行與上一步相同的查詢,結果 與上一步不一致,即產生了不可重複讀的問題

3、可重複讀

(1)開啟乙個客戶端a,並設定當前事務模式為repeatable read,查詢表account的所有記錄

(2)在客戶端a的事務提交之前,開啟另乙個客戶端b,更新表account並提交

(3)在客戶端a查詢表account的所有記錄,與步驟(1)查詢結果一致,沒有出現不可重複讀的問題

(4)在客戶端a,接著執行update balance = balance - 50 where id = 1,balance沒有變成400-50=350,lilei的balance值用的是步驟(2)中的350來算的,所以是300,資料的一致性倒是沒有被破壞。可重複讀的隔離級別下使用了mvcc機制,select操作不會更新版本號,是快照讀(歷史版本);insert、update和delete會更新版本號,是當前讀(當前版本)。

(5)重新開啟客戶端b,插入一條新資料後提交

(6)在客戶端a查詢表account的所有記錄,沒有 查出 新增資料,所以沒有出現幻讀

4.序列化

(1)開啟乙個客戶端a,並設定當前事務模式為serializable,查詢表account的初始值:

mysql> set session transaction isolation level serializable;

query ok, 0 rows affected (0.00 sec)

mysql> start transaction;

query ok, 0 rows affected (0.00 sec)

mysql> select * from account;

+------+--------+---------+

| id | name | balance |

+------+--------+---------+

| 1 | lilei | 10000 |

| 2 | hanmei | 10000 |

| 3 | lucy | 10000 |

| 4 | lily | 10000 |

+------+--------+---------+

4 rows in set (0.00 sec)

(2)開啟乙個客戶端b,並設定當前事務模式為serializable,插入一條記錄報錯,表被鎖了插入失敗,mysql中事務隔離級別為serializable時會鎖表,因此不會出現幻讀的情況,這種隔離級別併發性極低,開發中很少會用到。

mysql> set session transaction isolation level serializable;

query ok, 0 rows affected (0.00 sec)

mysql> start transaction;

query ok, 0 rows affected (0.00 sec)

mysql> insert into account values(5,'tom',0);

error 1205 (hy000): lock wait timeout exceeded; try restarting transaction

補充:

1、事務隔離級別為讀提交時,寫資料只會鎖住相應的行

2、事務隔離級別為可重複讀時,如果檢索條件有索引(包括主鍵索引)的時候,預設加鎖方式是next-key 鎖;如果檢索條件沒有索引,更新資料時會鎖住整張表。乙個間隙被事務加了鎖,其他事務是不能在這個間隙插入記錄的,這樣可以防止幻讀。

3、事務隔離級別為序列化時,讀寫資料都會鎖住整張表

4、隔離級別越高,越能保證資料的完整性和一致性,但是對併發效能的影響也越大。

mysql隔離級別 MySQL 事務隔離級別

mysql innodb所提供的事務滿足acid的要求,事務是通過事務日誌中的redo log和undo log來實現原子性 undo log 一致性 undo log 永續性 redo log 事務通過鎖機制實現隔離性。1 事務隔離級別與實現read uncommitted 讀未提交 read c...

MySQL事務隔離級別

sql標準定義了4類隔離級別,包括了一些具體規則,用來限定事務內外的哪些改變是可見的,哪些是不可見的。低階別的隔離級一般支援更高的 併發處理,並擁有更低的系統開銷。read uncommitted 讀取未提交內容 在該隔離級別,所有事務都可以看到其他未提交事務的執行結果。本隔離級別很少用於實際應用,...

Mysql 事務隔離級別

mysql 5.5預設儲存引擎 表型別 使用的是innodb,它是支援acid特性的 acid,指資料庫的原子性 atomicity 一致性 consistency 隔離性 isolation 永續性 durability 乙個支援事務 transaction 的資料庫系統,必需要具有這四種特性,否...