銀行引用是事務的一個經典例子:假如銀行有兩張表,一張支票表,一張儲蓄表,如今須要從Jones用戶的支票帳戶轉移200¥ 至儲蓄帳戶,那麼至少須要三步:
1. 檢查Jones的支票帳戶餘額是否大於200¥
2. Jones的支票帳戶-200¥
3. Jones的儲蓄帳戶+200¥
上述三步可組成一個事務,當二、3步故障時,以前執行的操做會自動回滾,保證數據的一致性。數據庫
MySQL事務是一組SQL語句或一個獨立運行的工做單元而且知足ACID測試。
ACID測試:
A.atomicity,原子性,一個事務必須做爲不可分割的最小單元,事務中的語句要麼都執行成功,要麼都執行失敗。
C.consistency,一致性,數據庫老是從一個一致性狀態到另外一個一致性狀態(數據庫的結果是一致的,全部事務中SQL語句共同修改後的結果)不可能由於系統奔潰出現上述支票表-200¥而儲蓄表未+200¥,未提交的事務並不會保存至數據庫中。
I. isolation ,隔離性,當前事務操做過程對於另外一個線程事務的可見度,由隔離級別決定。
D. durability , 持久性 , 全部事務提交後都永久存放於數據庫中。
ide
隔離級別:
1. READ UNCOMMITTED (讀未提交)
2. READ COMMITTED(讀提交)
3. REPEATEABLE READ(可重複讀)
4. SERIALIZABLE(序列化)
各個隔離級別可能產生的問題:測試
a.髒讀,當前線程事務能夠讀取另外一個線程事務未提交修改的數據。 b.不可重複讀,事務提交前看到的數據不一致(別的線程修改提交); 線程1開啓事務查詢數據一個樣,當線程2開啓事務修改提交後,線程1再次查詢發現數據修改(未提交),這就是不可重複讀。 c.幻讀, 可重複讀級別經過MVCC機制保證事務提交前看到的數據都是一致的,可是又有一個新問題,當線程2修改完數據提交後,線程1看到的仍是未修改前的原始數據,但實際底層數據已被更改,當線程1提交後發現數據改變,像幻覺同樣,這就是幻讀。 d.加鎖讀,SERIABLIZEBLE 爲了解決幻讀問題,當線程事務1查詢數據,線程事務2修改數據會被鎖住,由於數據具備不肯定性。
事務相關的命令:atom
START TRANSACTION #開啓事務 ROLLBACK #回滾事務 COMMIT #提交事務 SAVEPOINT identifier #事務語句過多時,能夠建立一個保存點,單獨還原至此點 ROLLBACK [WORK] TO [SAVEPOINT] identifier #還原事務至此點 RELEASE SAVEPOINT identifier #刪除保存點
1. READ UNCOMMITTED ——幻讀a.首先須要關閉事務自動提交功能
b.修改事務隔離級別爲READ-UNCOMMITTED
c.開啓事務功能
d.在一線程事務中修改數據但不提交,在另外一線程查看數據已更改,這就是髒讀,存在髒讀就必然存在不可重複讀、幻讀問題。
2. READ COMMITTED——解決髒讀,新問題:不可重複讀 a. 修改事務級別爲 READ-COMMITTED .
b. 開啓事務,並在一線程中刪除數據,另外一線程查看發現數據已更改,這就是不可重複讀。
3. REPEATEABLE READ——解決不可重複讀,新問題:幻讀a.修改事務級別爲REPEATABLE-READ
b.開啓事務、並查詢數據
c.線程2刪除數據並提交,線程1事務未提交查看數據發現未改變(可重複讀)
d.線程1提交事務發現數據已被改變,這就是幻讀,事務提交前數據已被改變,但沒法察覺到,事務未修改提交後卻發現數據改變
4. SERIALIZABLE——解決幻讀,新問題:加鎖讀 a.設置隔離級別爲SERIALIZABLE,在線程1查看數據,線程2修改數據發現被鎖住了,由於沒法保證線程1事務提交後看到的數據一致,這就是加鎖讀
線程
注意:須要先關閉autocommit=OFF ,而且須要在線程SELECT查看一次才能作出加鎖效果。3d