天天看點

mysql 事務特性以及隔離級别

1、前述

相信我們開發中會遇到各種各樣的異常,或者請求外部接口的異常,當用戶端向我們的服務端發起一次請求的時候,通常在業務裡會做一些資料庫增删改查的操作,然後做一些業務邏輯處理來傳回響應給用戶端,但是代碼裡出現異常是不可避免的,這個時候就需要我們來做一些資料庫復原的操作,也就是事務復原,否則就會出現很多的髒資料,影響系統後續的業務處理,本文是自己的一篇記錄和了解

2、資料庫事務復原

說到資料庫事務復原,這裡想提一點,Redis 是不支援事務復原的,redis 是先對記憶體中的資料進行操作,再寫入日志,這樣可以防止 aof 檔案寫入許多錯誤的指令,而 Mysql 例如 innodb 是支援事務的,先寫 redlog ,再對資料進行操作,

3、資料庫事務特性 ACID

A:Atomicity,原子性說到底就是,一條繩子上的螞蚱,誰都不能出事,一起成功一起失敗
C:consistency,一緻性也可以叫做資料完整性,事務在送出執行以後,必須有狀态的改變
I:isolation,隔離性,并發的多個事務之間不能資料幹擾,互相獨立隔離
D:durability,持久性,當事務送出以後,對資料庫進行的資料狀态操作應該被記錄下來,持久化儲存
           

4、資料庫隔離級别

4.1 隔離概念:

隔離級别是在多個事務同時進行更改和執行查詢時,對性能和結果的可靠性、一緻性和重制性之間的平衡進行微調的設定。

4.1 隔離級别:

InnoDB提供了SQL:1992标準描述的所有四個事務隔離級别:

READ UNCOMMITTED 讀取未送出
READ COMMITTED 讀取已送出
REPEATABLE READ 可重複讀
SERIALIZABLE 串行化
           

InnoDB 的預設隔離級别是

REPEATABLE READ

4.1.1 READ UNCOMMITTED

mysql 事務特性以及隔離級别

如圖,為一次示例讀取未送出,

t1 開啟事務 A
t2 開啟事務 B
t3 事務 A 查詢 username = ‘tanxi’
t4 事務 B 修改值 username = 'tanxi02'
t5 事務 A 查詢 username = 'tanxi02'
           

很明顯可以看出,事務 A 讀取到了 事務 B 的未送出的資料,造成了髒讀,這是最不安全的隔離級别,這種隔離級别解決不了任何問題

4.1.2 READ COMMITTED

mysql 事務特性以及隔離級别

如圖,為一次示例讀取已送出

t1 開啟事務 A
    t2 開啟事務 B
    t3 事務 A 查詢 username = ‘tanxi’
    t4 事務 B 修改值 username = 'tanxi02'
    t5 事務 A 查詢 username = 'tanxi'
    t6 事務 B 送出事務
    t7 事務 A 查詢 username = 'tanxi02'
           

該隔離級别解決了 4.1.1 的髒讀,但是不能解決不可重複讀,這是不被允許的資料讀取方式

4.1.3 REPEATABLE READ

mysql 事務特性以及隔離級别

如圖,為一次示例可重複讀

t1 開啟事務 A
t2 開啟事務 B
t3 事務 A 查詢 username = ‘tanxi’
t4 事務 B 修改值 username = 'tanxi02'
t5 事務 A 查詢 username = 'tanxi'
t6 事務 B 送出事務
t7 事務 A 查詢 username = 'tanxi'     
           

該隔離級别解決了不可重複讀的問題,事務 B 的事務送出沒有影響到事務 A 的查詢結果

4.1.4 SERIALIZABLE

mysql 事務特性以及隔離級别

如圖,為一次示例串行化

t1 開啟事務 A
t2 開啟事務 B
t3 事務 A 查詢 username = ‘tanxi’
t4 事務 B 修改值 username = 'tanxi02'
t5 事務 A 查詢 ,阻塞等待
t6 事務 B 送出事務
t7 事務 A 查詢 username = 'tanxi'
           

該隔離級别可以避免髒讀以及不可重複讀,但是會阻塞 sql,也就是寫讀不能并發。性能很差

5、總結說明

在 mysql 的 innodb 引擎中,InnoDB 引擎預設的行鎖算法.,Next-Key locks 可以避免幻讀,有興趣的同學可以去官網了解。https://dev.mysql.com/doc/refman/5.7/en/

繼續閱讀