mysql事務回滾機制概述

應用場景:
   銀行取錢,從ATM機取錢,分爲以下幾個步驟
       1 登陸ATM機,輸入密碼;
    2 連接數據庫,驗證密碼;
    3 驗證成功,獲得用戶信息,比如存款餘額等;
    4 用戶輸入需要取款的金額,按下確認鍵;
    5 從後臺數據庫中減掉用戶賬戶上的對應金額;
    6 ATM吐出錢;
    7 用戶把錢拿走。
    對於上面的取錢這個事情,如果有一步出現錯誤的話,那麼就會取消整個取錢的動作,但是如果在第5步,系統後臺已經把錢減了,但是ATM機沒有取出來,那麼就應用到mysql中的事務。簡單地
來說,就是取錢這7步要麼都完成,要麼就啥也不做,在數據庫中就是這個道理。


    事務是用戶定義的一個數據庫操作序列,這些操作要麼全做要麼全不做,是一個不可分割的工作單位,事務回滾是指將該事務已經完成的對數據庫的更新操作撤銷,在事務中,每個正確的原子
操作都會被順序執行,直到遇到錯誤的原子操作。回滾的意思其實即使如果之前是插入操作的話,那麼會執行刪除之前插入的記錄,如果是修改操作的話,那麼會執行將update之前的記錄還原。
因此,正確的原子操作是真正被執行過的,是物理執行。

    事務是由一條或者多條sql語句組成,在事務的操作中,要麼這些sql語句都執行,要麼都不執行。

    事務的ACID特性:原子性,一致性,隔離性,持久性。
   
   在當前事務中確實能看到插入的記錄,最後只不過被刪除了,但是auto_increament不會刪除而是改變值


   爲什麼auto_increament沒有回滾:因爲innodb存儲引擎中的auto_increment就是主鍵的計數記錄的當前值是保存在內存中,並不是存在磁盤中的,當mysql server處於運行的時候,這個計數值只會隨着
insert增長,不會隨着delete減少。而當mysql server啓動的時候,當我們需要查詢auto_increment計數值時,mysql便會自動執行:SELECT MIX(ID) FROM 表名 FOR UPDATE;這條語句來獲得auto_increment
列的最大值,然後將這個值放到auto_increment計數器中,所以ROLLBACK MYSQL的auto_increment計數器也不會做負運算


    事務分爲哪些種:扁平事務,帶有保存點扁平事務,鏈事務,嵌套事務,分佈式事務。


    MYSQL中使用事務:
  在MYSQL命令行命令下事務都是自動提交的,即執行Sql語句就會馬上執行COMMIT操作。因此要顯示一個事務的開啓必須使用命令BEGIN或者START TRANSACTION,或者執行命令SET AUTOCOMMIT=0來
禁止當前回話的自動提交


   事務控制語句:
BEGIN/START TRANSACTION:顯示地開啓一個事務
COMMIT:也可以使用COMMIT WORK 兩者是等價的。COMMIT會提交事務,並是已對數據庫進行的所有的修改是永久性的。
ROLLBACK:也可以使用ROLLBACK WORK,兩者也是等價的,回滾會結束用戶的事務,並且會撤銷正在進行的所有未提交的修改。
SAVEPOINT identifier:允許在事務中創建一個保存點,一個事務中可以有多個SAVEPOINT
release SAVEPOINT identifier:刪除一個事務的保存點,當沒有制定的保存點,會拋出一個異常。 
SET TRANSACTION:用來設置事務的隔離級別。Innodb存儲引擎提供的事務隔離級別有READ UNCOMMITED,READ COMMITED,REPEATABLE READ和SERIALIZABLE.
   
    事務的隔離級別:在數據庫操作中,爲了保證併發讀取數據的正確性,提出了隔離級別,如上
  區別如下:
  隔離級別 髒讀(Dirty Read) 不可重複讀(NonRepeatable Read) 幻讀(Phantom Read)
  未提交讀 read uncommited 可能 可能 可能
  已提交讀 read commited 不可能 可能 可能
  可重複讀 repeatable read 不可能 不可能 可能
  可串行化 serializable 不可能 不可能 不可能


   髒讀:一個事務讀取到了另一個事務沒有提交的數據
例如:事務T1更新了一行記錄的內容,但是並沒有提交所做的修改。事務T2讀取到了T1更新後的行,然後T1執行回滾操作,取消了剛纔所做的修改。現在T2所讀取的行就無效了


   不可重複讀:在同一事務中,兩次讀取同一數據,得到的內容不同
例如:事務T1讀取一行記錄,緊接着事務T2修改了T1剛纔讀取的那一行記錄。然後T1又再次讀取這行記錄,發現與剛纔讀取的結果不同。這就稱爲“不可重複”讀,因爲T1原來讀取的那行記錄已經發生了變化


   幻讀:在同一事務中,用同樣的操作讀取兩次,得到的記錄數不同
例如:事務T1讀取一條指定的WHERE子句所返回的結果集。然後事務T2新插入 一行記錄,這行記錄恰好可以滿足T1所使用的查詢條件中的WHERE子句的條件。然後T1又使用相同的查詢再次對錶進行檢索,
     但是此時卻看到了事務T2剛纔插入的新行。這個新行就稱爲“幻像”,因爲對T1來說這一行就像突然出現的一樣
   
   隔離級別越低,事務請求的瑣越少或者說是保持瑣的時間越短,Innodb存儲引擎默認支持的隔離界別是REPEATALE READ;在這種默認的事務隔離級別下已經能完全保證事務的隔離性。  


   mysql事務回滾怎樣實現的代碼可以參考此bolg:http://bbs.csdn.net/topics/390876901 

   要同時修改數據庫中兩個不同表時,如果它們不是一個事務的話,當第一個表修改完,可能第二個表修改過程中出現了異常而沒能修改,此時就只有第二個表依舊是未修改之前的狀態,
   而第一個表已經被修改完畢。而當你把它們設定爲一個事務的時候,當第一個表修改完,第二表修改出現異常而沒能修改,第一個表和第二個表都要回到未修改的狀態,這就是所謂的事務回滾。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章