1. 程式人生 > >MYSOL 學習筆記之事務處理

MYSOL 學習筆記之事務處理

log lba 方法 我們 mysql status user 恢復 讀取

1 事務隔離性實現原理

  數據庫事務會導致臟讀、不可重復讀和幻影讀等問題。

  臟讀:事務還沒提交,他的修改已經被其他事務看到。

  不可重復讀:同一事務中兩個相同SQL讀取的內容可能不同。兩次讀取之間其他事務提交了修改可能會造成讀取數據不一致。

  幻影數據:同一個事務突然發現他以前沒發現的數據。和不可重復讀很類似,不過修改數據改成增加數據。

針對可能的問題,InnoDB提供了四種不同級別的機制保證數據隔離性。

  事務的隔離用是通過鎖機制實現的,不同於MyISAM使用表級別的鎖,InnoDB采用更細粒度的行級別鎖,提高了數據表的性能。InnoDB的鎖通過鎖定索引來實現,如果查詢條件中有主鍵則鎖定主鍵,如果有索引則先鎖定對應索引然後再鎖定對應的主鍵(可能造成死鎖),如果連索引都沒有則會鎖定整個數據表。

1.1 READ UNCOMMIT

  READ UNCOMMIT允許某個事務看到其他事務並沒有提交的數據。可能會導致臟讀、不可重復讀、幻影數據。

  原理:READ UNCOMMIT不會采用任何鎖。

1.2 READ COMMIT

**可能有誤,學習時沒看到多版本並發控制(MVCC),學習後更新**

  READ COMMIT允許某個事務看到其他事務已經提交的數據。可能會導致不可重復讀和幻影數據。

  原理:數據的讀是不加鎖的,但是數據的寫入、修改、刪除加鎖,避免了臟讀。

1.3 REPEATABLE READ

**可能有誤,學習時沒看到多版本並發控制(MVCC),學習後更新**

InnoDB中REPEATABLE READ級別同一個事務的兩次相同讀取肯定是一樣的,其他事務的提交不會對本次事務有影響。

  原理:數據的讀、寫都會加鎖,當前事務如果占據了鎖,其他事務必須等待本次事務提交完成釋放鎖後才能對相同的數據行進行操作。

1.4 SERIALIZABLE

**可能有誤,學習時沒看到多版本並發控制(MVCC),學習後更新**

  SERIALIZABLE 級別在InnoDB中和REPEATABLE READ采用相同的實現

2. 原子性、穩定性和持久性實現原理

  原子性、穩定性和持久性是通過redo 和 undo 日誌文件實現的,不管是redo還是undo文件都會有一個緩存我們稱之為redo_buf和undo_buf。同樣,數據庫文件也會有緩存稱之為data_buf。

2.1 undo 日誌文件

  undo記錄了數據在事務開始之前的值,當事務執行失敗或者ROLLBACK時可以通過undo記錄的值來恢復數據。例如 AA和BB的初始值分別為3,5。

A 事務開始

B 記錄AA=3到undo_buf

C 修改AA=1

D 記錄BB=5到undo_buf

E 修改BB=7

F 將undo_buf寫到undo(磁盤)

G 將data_buf寫到datafile(磁盤)

H 事務提交

  通過undo可以保證原子性、穩定性和持久性

  如果事務在F之前崩潰由於數據還沒寫入磁盤,所以數據不會被破壞。

  如果事務在G之前崩潰或者回滾則可以根據undo恢復到初始狀態。

  數據在任務提交之前寫到磁盤保證了持久性。

  但是單純使用undo保證原子性和持久性需要在事務提交之前將數據寫到磁盤,浪費大量I/O。

2.2 redo/undo 日誌文件

  引入redo日誌記錄數據修改後的值,可以避免數據在事務提交之前必須寫入到磁盤的需求,減少I/O。

A 事務開始

B 記錄AA=3到undo_buf

C 修改AA=1 記錄redo_buf

D 記錄BB=5到undo_buf

E 修改BB=7 記錄redo_buf

F 將redo_buf寫到redo(磁盤)

G 事務提交

  通過undo保證事務的原子性,redo保證持久性。

  F之前崩潰由於所有數據都在內存,恢復後重新沖磁盤載入之前的數據,數據沒有被破壞。

  FG之間的崩潰可以使用redo來恢復。

G之前的回滾都可以使用undo來完成。

3.事務操作命令

  如果需要使用事務就必須選用支持事務的數據庫引擎如InnoDB和Falcon,MyISAM並不支持事務。

  在默認情況下MySQL開啟的是autocommit模式,也就是隱含的將每條語句當做一個事務處理,每條SQL都會被自動提交。當我們使用BEGIN或者START TRANSCATION時會把自動提交掛起,直到顯示的調用COMMIT。使用事務可以有如下兩種方法:

1.BEGIN; //開始事務,掛起自動提交

2.insert into t_cart_shopcart (user_id, sku_id, amount, shop_id, status) values(10001, 10001, 1, 10001, 0);

3.insert into t_cart_shopcart (user_id, sku_id, amount, shop_id, status) values(10001, 10002, 1, 10001, 0);

4.COMMIT; //提交事務,恢復自動提交

1.set autocommit = 0; //掛起自動提交

2.insert into t_cart_shopcart (user_id, sku_id, amount, shop_id, status) values(10001, 10001, 1, 10001, 0);

3.insert into t_cart_shopcart (user_id, sku_id, amount, shop_id, status) values(10001, 10002, 1, 10001, 0);

4.COMMIT; //提交事務set autocommit = 1; //恢復自動提交

  這兩種方式效果相同。

參考:http://blog.csdn.net/sk199048/article/details/50596092

MYSOL 學習筆記之事務處理