要想知道什麼是數據庫事務,首先要知道爲何數據庫須要事務管理。java
要說事務的例子,最簡單的就是銀行轉帳,A向B轉帳100,首先要將A記錄中的金額減去100,再將B記錄中的金額加上100,這纔算是完成一次轉帳。但是,程序運行中可能出現各類不可控因素,若是在A減去100以後,銀行停電或者地震之類的,各類緣由致使程序中止,並無執行對B帳戶的操做,A減去了100,但是B沒有加上。這時候就須要事務管理。mysql
一、通常來講,事務是必須知足4個條件(ACID)sql
原子性(Autmic):事務在執行性,就是說不容許事務部分得執行,一個事務是一個不可分割的工做單位。即便由於故障而使事務不能完成,rollback後也要回退到對數據庫進行操做前的狀態。數據庫
一致性(Consistency):事務必須是使數據庫從一個一致性狀態變到另外一個一致性狀態。一致性與原子性是密切相關的。好比A,B帳戶相互轉帳以後,總金額不變。服務器
隔離性(Isolation):一個事務的執行不能被其餘事務干擾,當多個事務併發執行時,各個事務不會互相影響。併發
持久性(Durability):持續性也稱永久性(permanence),指一個事務一旦提交,它對數據庫中數據的改變就應該是永久性的。spa
二、事務的四個特性(ACID)是由關係數據庫管理系統(RDBMS,數據庫系統)來實現的。數據庫管理系統採用日誌來保證事務的原子性、一致性和持久性。日誌記錄了事務對數據庫所作的更新,若是某個事務在執行過程當中發生錯誤,就能夠根據日誌,撤銷事務對數據庫已作的更新,使數據庫退回到執行事務前的初始狀態。線程
數據庫管理系統採用鎖機制來實現事務的隔離性。當多個事務同時更新數據庫中相同的數據時,只容許持有鎖的事務能更新該數據,其餘事務必須等待,直到前一個事務釋放了鎖,其餘事務纔有機會更新該數據。日誌
一、髒讀(DirtyReads):所謂髒讀就是對髒數據(Drity Data)的讀取,而髒數據所指的就是未提交的數據。一個事務正在對一條記錄作修改,在這個事務完成並提交以前,這條數據是處於待定狀態的(可能提交也可能回滾),這時,第二個事務來讀取這條沒有提交的數據, 並據此作進一步的處理,就會產生未提交的數據依賴關係。code
二、不可重複讀(Non-RepeatableReads):一個事務前後讀取同一條記錄,期間另外一個事務修改了數據,而且已經commit,因此兩次讀取的數據不一樣,稱之爲不可重複讀。 三、幻讀(PhantomReads):一個事務前後讀取同一個表,期間其餘事務插入了新的數據,而且已經commit,這種現象就稱爲幻讀。 它和不可重複讀的區別:不可重複讀的重點是修改,幻讀重點是新增和修改。
既然知道了事務會有髒讀,不可重複讀和幻讀的現象,那就須要去控制他們,因此有了隔離級別。 通常隔離級別有四級:
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
複製代碼
1.InnoDB採用的是兩階段鎖定協議。事務執行過程當中,隨時均可以鎖定,在執行COMMIT或者ROLLBACK的時候纔會釋放。InnoDB還會根據隔離級別在須要的時候自動加鎖。
2.InnoDB也支持經過特定的語句進行顯示鎖定。
SELECT XXX LOCK IN SHARE MODE
SELECT XXX FOR UPDATE
複製代碼
MYSQL也支持LOCK TABLES 和UNLOCK TABLES,這是服務器層實現的,和存儲引擎無關。