MySQL 事務

銀行引用是事務的一個經典例子:假如銀行有兩張表,一張支票表,一張儲蓄表,如今須要從Jones用戶的支票帳戶轉移200¥ 至儲蓄帳戶,那麼至少須要三步:
    1. 檢查Jones的支票帳戶餘額是否大於200¥
    2. Jones的支票帳戶-200¥
    3. Jones的儲蓄帳戶+200¥
上述三步可組成一個事務,當二、3步故障時,以前執行的操做會自動回滾,保證數據的一致性。數據庫

    

1、MySQL事務

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修改數據會被鎖住,由於數據具備不肯定性。

MySQL 事務
事務相關的命令:atom

START   TRANSACTION       #開啓事務
ROLLBACK        #回滾事務
COMMIT             #提交事務
SAVEPOINT identifier          #事務語句過多時,能夠建立一個保存點,單獨還原至此點
ROLLBACK [WORK] TO [SAVEPOINT] identifier        #還原事務至此點
RELEASE SAVEPOINT identifier                                 #刪除保存點

2、驗證各事務隔離級別存在的問題:

 
1. READ UNCOMMITTED ——幻讀
a.首先須要關閉事務自動提交功能
MySQL 事務
b.修改事務隔離級別爲READ-UNCOMMITTED
MySQL 事務
c.開啓事務功能
MySQL 事務
d.在一線程事務中修改數據但不提交,在另外一線程查看數據已更改,這就是髒讀,存在髒讀就必然存在不可重複讀、幻讀問題。
MySQL 事務
2. READ COMMITTED——解決髒讀,新問題:不可重複讀
a. 修改事務級別爲 READ-COMMITTED .
MySQL 事務
b. 開啓事務,並在一線程中刪除數據,另外一線程查看發現數據已更改,這就是不可重複讀。
MySQL 事務
MySQL 事務
3. REPEATEABLE READ——解決不可重複讀,新問題:幻讀
a.修改事務級別爲REPEATABLE-READ
MySQL 事務
b.開啓事務、並查詢數據
MySQL 事務
c.線程2刪除數據並提交,線程1事務未提交查看數據發現未改變(可重複讀)
MySQL 事務
d.線程1提交事務發現數據已被改變,這就是幻讀,事務提交前數據已被改變,但沒法察覺到,事務未修改提交後卻發現數據改變
MySQL 事務
4. SERIALIZABLE——解決幻讀,新問題:加鎖讀
a.設置隔離級別爲SERIALIZABLE,在線程1查看數據,線程2修改數據發現被鎖住了,由於沒法保證線程1事務提交後看到的數據一致,這就是加鎖讀
MySQL 事務線程

注意:須要先關閉autocommit=OFF ,而且須要在線程SELECT查看一次才能作出加鎖效果。3d

相關文章
相關標籤/搜索