MySql事務特性、隔離級別

事務

現在的軟件都是大併發的操作數據,然而爲了保證操作數據的正確性。就提出了事務。

事務的特性

事務必須滿足的4個條件(ACID):原子性(Atomicity)、一致性(Consistency)、隔離性(Isolation)和持久性(Durability)。

  1. 原子性:一個事務(Transaction)中的所有操作要麼都執行成功,要麼都失敗。事務在執行過程中,如果發生錯誤則會回滾(Rollback)到事務開始前的狀態,就像這個事務從來沒有執行過。數據不會有任何改變。
  2. 一致性:在事務開始前和結束後,數據的完整性沒有被破壞。
  3. 隔離性:數據庫允許多個事務併發對其數據進行讀取和修改,隔離性是防止多個事務交叉執行時讀取數據不一致問題。事務的隔離級別分爲,未提交讀(Read uncommitted)、提交讀(Read committed)、可重複讀(Repeatable read)和串行化(Serializable)。
  4. 持久性:事務提交後,對數據的修改是永久性的,提交的數據不會丟失。

事務的隔離級別

  1. 未提交讀(Read uncommitted):可以讀取其它所有事務未提交事務的執行結果。讀取未提交的數據,稱之爲髒讀(Dirty Read)。
  2. 提交讀(Read committed):一個事務只能讀取其它事務已提交的數據。
  3. 可重複讀(Repeatable read):保證同一事務的多個實例在併發讀取數據時,會看到同樣的數據行。MySQL默認隔離級別。
  4. 串行化(Serializable):每個事務排隊執行,最高的隔離級別,避免了髒讀不可重複讀幻讀
舉例
  1. 用到的MySQL命令
命令 作用
select version(); 查看數據庫版本
select @@tx_isolation;# 8以前版本
select @@transaction_isolation;# 8以後版本
查看當前事務隔離級別
set session transaction isolation level 隔離級別 當前會話的隔離級別
start transaction 開啓事務
commit 提交事務
rollback 回滾事務
  1. 建表
CREATE TABLE `tb_account` (
  `id` bigint(10) NOT NULL AUTO_INCREMENT COMMENT '主鍵',
  `name` varchar(10) DEFAULT NULL COMMENT '姓名',
  `balance` decimal(10,4) DEFAULT NULL COMMENT '餘額',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
  1. 髒讀
順序 會話1 會話2
1 # 設置隔離級別爲 未提交讀
set session transaction isolation level read uncommitted;
2 # 開啓事務
start TRANSACTION;
# 開啓事務
start TRANSACTION;
3 在這裏插入圖片描述
4 在這裏插入圖片描述
5 在這裏插入圖片描述
6 在這裏插入圖片描述
7 在這裏插入圖片描述

在會話1中,順序7查詢結果爲會話2中未提交事務修改的數據,即是 髒讀

  1. 不可重複讀
順序 會話1 會話2
1 # 設置隔離級別爲 提交讀
set session transaction isolation level read committed;
2 # 開啓事務
start TRANSACTION;
# 開啓事務
start TRANSACTION;
3 在這裏插入圖片描述
4 在這裏插入圖片描述
5 在這裏插入圖片描述

在會話1中,順序3和5讀取到的數據不同,是因爲其間會話2對數據進行了修改,並提交。如果不提交,查詢餘額依然是0,避免了髒讀。一個事務中兩次的查詢結果不一致,即爲不可重複讀。

  1. 可重複讀
順序 會話1 會話2
1 # 設置隔離級別爲 可重複讀
set session transaction isolation level REPEATABLE read;
2 # 開啓事務
start TRANSACTION;
# 開啓事務
start TRANSACTION;
3 在這裏插入圖片描述
4 在這裏插入圖片描述
5 在這裏插入圖片描述

與不可重複讀的區別在於,無論會話2的事務是否已經提交,都不會改變會話1的查詢結果。

  1. 幻讀

所謂幻讀,指的是當某個事務在讀取某個範圍內的記錄時,另外一個事務又在該範圍內插入了新的記錄,當之前的事務再次讀取該範圍的記錄時,會產生幻行。InnoDB存儲引擎通過多版本併發控制(MVCC)解決了幻讀的問題。

順序 會話1 會話2
1 # 設置隔離級別爲 可重複讀
set session transaction isolation level REPEATABLE read;
2 # 開啓事務
start TRANSACTION;
# 開啓事務
start TRANSACTION;
3 在這裏插入圖片描述
4 INSERT INTO tb_account VALUE (3, ‘王五’, 1000);
COMMIT;
在這裏插入圖片描述
5 在這裏插入圖片描述

在會話1中順序3查詢id爲3的記錄爲空,此時,會話2插入id爲3的數據,並提交。會話1再去插入id爲3的數據時就會報主鍵衝突異常。即爲幻讀。
防止讀到修改或刪除數據需要加行級鎖。
防止讀到新增數據一般就需要加表級鎖。

不可重複讀和幻讀的區別在於,不可重複讀會讀到修改或者刪除的數據,幻讀是會讀到其它事務已提交的數據。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章