MySQL的事務處理及隔離級別

要想知道什麼是數據庫事務,首先要知道爲何數據庫須要事務管理。java

要說事務的例子,最簡單的就是銀行轉帳,A向B轉帳100,首先要將A記錄中的金額減去100,再將B記錄中的金額加上100,這纔算是完成一次轉帳。但是,程序運行中可能出現各類不可控因素,若是在A減去100以後,銀行停電或者地震之類的,各類緣由致使程序中止,並無執行對B帳戶的操做,A減去了100,但是B沒有加上。這時候就須要事務管理。mysql

1、事務的四個特性

一、通常來講,事務是必須知足4個條件(ACID)sql

原子性(Autmic):事務在執行性,就是說不容許事務部分得執行,一個事務是一個不可分割的工做單位。即便由於故障而使事務不能完成,rollback後也要回退到對數據庫進行操做前的狀態。數據庫

一致性(Consistency):事務必須是使數據庫從一個一致性狀態變到另外一個一致性狀態。一致性與原子性是密切相關的。好比A,B帳戶相互轉帳以後,總金額不變。服務器

隔離性(Isolation):一個事務的執行不能被其餘事務干擾,當多個事務併發執行時,各個事務不會互相影響。併發

持久性(Durability):持續性也稱永久性(permanence),指一個事務一旦提交,它對數據庫中數據的改變就應該是永久性的。spa

二、事務的四個特性(ACID)是由關係數據庫管理系統(RDBMS,數據庫系統)來實現的。數據庫管理系統採用日誌來保證事務的原子性、一致性和持久性。日誌記錄了事務對數據庫所作的更新,若是某個事務在執行過程當中發生錯誤,就能夠根據日誌,撤銷事務對數據庫已作的更新,使數據庫退回到執行事務前的初始狀態。線程

數據庫管理系統採用鎖機制來實現事務的隔離性。當多個事務同時更新數據庫中相同的數據時,只容許持有鎖的事務能更新該數據,其餘事務必須等待,直到前一個事務釋放了鎖,其餘事務纔有機會更新該數據。日誌

2、關於髒讀,不可重複讀、幻讀

一、髒讀(DirtyReads):所謂髒讀就是對髒數據(Drity Data)的讀取,而髒數據所指的就是未提交的數據。一個事務正在對一條記錄作修改,在這個事務完成並提交以前,這條數據是處於待定狀態的(可能提交也可能回滾),這時,第二個事務來讀取這條沒有提交的數據, 並據此作進一步的處理,就會產生未提交的數據依賴關係。code

二、不可重複讀(Non-RepeatableReads):一個事務前後讀取同一條記錄,期間另外一個事務修改了數據,而且已經commit,因此兩次讀取的數據不一樣,稱之爲不可重複讀。 三、幻讀(PhantomReads):一個事務前後讀取同一個表,期間其餘事務插入了新的數據,而且已經commit,這種現象就稱爲幻讀。 它和不可重複讀的區別:不可重複讀的重點是修改,幻讀重點是新增和修改。

3、隔離級別

既然知道了事務會有髒讀,不可重複讀和幻讀的現象,那就須要去控制他們,因此有了隔離級別。 通常隔離級別有四級:

READ UNCOMMITTED:幻讀,不可重複讀和髒讀均容許
複製代碼

若是數據庫的隔離級別爲REAE UNCOMMITTED, 則其餘線程能夠看到未提交的數據, 所以就出現髒讀。

READ COMMITTED:容許幻讀和不可重複讀,但不容許髒讀
複製代碼

若是數據庫隔離級別設爲READ_COMMITTED,即沒提交的數據別人是看不見的,就避免了髒讀.可是,正在讀取的數據只得到了讀取鎖,讀完以後就解鎖,無論當前事務有沒有結束,這樣就允許其餘事務修改本事務正在讀取的數據。致使不可重複讀。

REPEATABLE READ:容許幻讀,但不容許不可重複讀和髒讀
複製代碼

REPEATABLE READ由於對正在操做的數據加鎖,而且只有等到事務結束才放開鎖, 則能夠避免不可重複讀。

SERIALIZABLE:幻讀,不可重複讀和髒讀都不容許
複製代碼

SERIALIZABLE由於得到範圍鎖,且事務是一個接着一個串行執行,則保證了不會發生幻讀。

隔離級別 髒讀可能性 不可重複讀可能性 幻讀可能性 加鎖讀
READ UNCOMMITTED YES YES YES NO
READ COMMITTED NO YES YES NO
REPEATABLE READ NO NO YES NO
SERIALIZABLE NO NO NO YES

因此說,READ UNCOMMITTED級別最低,SERIALIZABLE級別最高。 級別越高確定對於維護事務的四個特性就越好,可是它犧牲的是數據庫的效率,由於SERIALIZABLE的實現是相似於java中的線程鎖。

ORACLE默認的是 READ COMMITTED,默認事務管理是開啓的,使用DML語言對數據操做須要提交(commit),出錯後能夠回滾(rollback)。MYSQL默認的是 REPEATABLE READ,事務默認自動提交,若想開啓事務,使用set autocommit 命令。

Mysql提供了兩種事務型的存儲引擎:InnoDB和NDB Cluster.經過執行SET TRANSACTION ISOLATION LEVEL 設置隔離級別。新的隔離界別會在下一個事務開始時生效,也能夠在配置文件中設置整個數據庫的隔離級別。

mysql>SET SESSION TRANSACTION ISOLATION LEVEL  READ COMMITTED
複製代碼

4、隱式和顯式鎖定

1.InnoDB採用的是兩階段鎖定協議。事務執行過程當中,隨時均可以鎖定,在執行COMMIT或者ROLLBACK的時候纔會釋放。InnoDB還會根據隔離級別在須要的時候自動加鎖。

2.InnoDB也支持經過特定的語句進行顯示鎖定。

SELECT XXX LOCK IN SHARE MODE

SELECT XXX FOR UPDATE
複製代碼

MYSQL也支持LOCK TABLES 和UNLOCK TABLES,這是服務器層實現的,和存儲引擎無關。

相關文章
相關標籤/搜索