1. 程式人生 > >mysql之事務詳解

mysql之事務詳解

我們知道,應用中的一個業務邏輯,往往由多條語句組合完成。那麼我們就可以簡單地將事務理解為一組SQL語句的集合,要麼這個集合全部成功集合,要麼這個集合就全部失敗退回到第一句之前的狀態。

語法

我們先來看看事務的語法。現在的社會比較浮躁,大家往往只在乎如何解決問題,而不去考慮問題的本質到底是什麼。

所以我決定先來介紹事務的語法
1. 開啟事務start transaction,可以簡寫為 begin
2. 然後記錄之後需要執行的一組sql
3. 提交commit
4. 如果所有的sql都執行成功,則提交,將sql的執行結果持久化到資料表內。
5. 回滾rollback
6. 如果存在失敗的sql,則需要回滾,將sql的執行結果,退回到事務開始之時
7. 無論回滾還是提交,都會關閉事務

!需要再次開啟,才能使用。
8. 還有一點需要注意,就是事務只針對當前連線

下面我們來進行演示:

使用第一個連結A,開啟事務後,執行一條update語句。
結果成功,資料已經變成修改之後!

這裡寫圖片描述

此時我們沒有提交。
再從其他連線B來檢視,發現數據為更改:

這裡寫圖片描述

此時如果連線A選擇提交,也就是commit操作。則連線B的資料也會發生變化。

而如果連線A選擇回滾,也就是rollback操作。則連線A再次查詢則發現數據還原。

基本原理

語法說完了,浮躁的人也不用繼續看下去了。下面簡單說一下事務的基本原理吧。
提交,就會將結果持久化,不提交就不會。
如果我們不開啟事務,只執行一條sql,馬上就會持久化資料

,可以看出,普通的執行就是立即提交。
這是因為mysql預設對sql語句的執行是自動提交的

也就是說,開啟事務,實際上就是關閉了自動提交的功能,改成了commit手動提交!

我們可以通過簡單的對是否自動提交加以設定,完成開啟事務的目的!
自動提交的特徵是儲存在服務的一個autocommit的變數內。可以進行修改:

這裡寫圖片描述

還需要注意一點,就是事務類似於外來鍵約束,只被innodb引擎支援。

特點

下面來說說事務的特點ACID。也就是原子性一致性隔離性永續性

原子性:事務是不可分割的。
一致性:保證資料在事務的執行週期內,是一致的!
隔離型:多個事務之間的干擾關係!隔離級別!
永續性

:事務一旦被提交,就不可能再被回滾!

事務併發

事務併發會帶來一些問題,所以才有了不同的事務隔離級別。要想了解事務的隔離級別,就必須首先了解事務併發會帶來的問題。
一般來說,會出現三類資料讀問題和資料更新問題。

髒讀

一個事務正在對一條記錄做修改,但未提交,另一個事務讀取了這些髒資料,並進一步處理,就會產生未提交的資料依賴。
舉一個例子:

時間 轉賬事務A 取款事務B
T1 開始事務
T2 開始事務
T3 查詢賬戶餘額為1000元
T4 取出500元把餘額改為500元
T5 查詢賬戶餘額為500元(髒讀)
T6 撤銷事務餘額恢復為1000元
T7 匯入100元把餘額改為600元
T8 提交事務

A讀取了B尚未提交的髒數,導致最後餘額為600元。

不可重複讀

一個事務在不同時間讀取資料不一致。
舉一個例子:

時間 取款事務A 轉賬事務B
T1 開始事務
T2 開始事務
T3 查詢賬戶餘額為1000元
T4 查詢賬戶餘額為1000元
T5 取出100元把餘額改為900元
T6 提交事務
T7 查詢賬戶餘額為900元(和T4讀取的不一致)

可以看到最後讀取的資料不一致。

幻讀

幻讀和不可重複讀的概念類似,都是不同時間資料不一致,只不過幻讀是針對新增資料,而不可重複讀是針對更改資料。
看一個例子:

時間 統計金額事務A 轉賬事務B
T1 開始事務
T2 開始事務
T3 統計總存款數為10000元
T4 新增一個存款賬戶,存款為100元
T5 提交事務
T6 再次統計總存款數為10100元(幻象讀)

更新丟失

兩個事務對同一資料進行更新,後者會覆蓋先者的更新。

時間 取款事務A 轉賬事務B
T1 開始事務
T2 開始事務
T3 查詢賬戶餘額為1000元
T4 查詢賬戶餘額為1000元
T5 匯入100元把餘額改為1100元
T6 提交事務
T7 取出100元將餘額改為900元
T8 撤銷事務
T9 餘額恢復為1000元(丟失更新)

隔離級別

事務併發帶來的問題前文已經描述得非常仔細了。事務的隔離級別就是為了針對併發出現的問題,不同的級別可以保證不同的一致性。

為了解決上面講到的併發事務處理帶來的問題,SQL標準提出了4個等級的事務隔離級別。不同的隔離級別在同樣的環境下會出現不同的結果。
下面看看四種隔離級別的比較

隔離級別 讀資料一致性 髒讀 不可重複讀 幻讀
未提交讀(Read uncommitted) 最低級別,只能保證不讀取物理上損壞的資料
已提交讀(Read committed) 語句級
可重複讀(Repeatable read) 事務級
可序列化(Serializable) 最高級別,事務級