什麼是MySQL? MySQL 是一種關係型數據庫,在Java企業級開發中很是經常使用,由於 MySQL 是開源免費的,而且方便擴展。阿里巴巴數據庫系統也大量用到了 MySQL,所以它的穩定性是有保障的。MySQL是開放源代碼的,所以任何人均可以在 GPL(General Public License) 的許可下下載並根據個性化的須要對其進行修改。MySQL的默認端口號是3306。
**事務是邏輯上的一組操做,要麼都執行,要麼都不執行。** 事務最經典也常常被拿出來講例子就是轉帳了。假如小明要給小紅轉帳1000元,這個轉帳會涉及到兩個關鍵操做就是:將小明的餘額減小1000元,將小紅的餘額增長1000元。萬一在這兩個操做之間忽然出現錯誤好比銀行系統崩潰,致使小明餘額減小而小紅的餘額沒有增長,這樣就不對了。事務就是保證這兩個關鍵操做要麼都成功,要麼都要失敗。
在典型的應用程序中,多個事務併發運行,常常會操做相同的數據來完成各自的任務(多個用戶對統一數據進行操做)。
髒讀(Dirty read):mysql
當一個事務正在訪問數據而且對數據進行了修改,而這種修改尚未提交到數據庫中,這時另一個事務也訪問了這個數據,而後使用了這個數據。由於這個數據是尚未提交的數據,那麼另一個事務讀到的這個數據是「髒數據」,依據「髒數據」所作的操做多是不正確的。
丟失修改(Lost to modify):算法
指在一個事務讀取一個數據時,另一個事務也訪問了該數據,那麼在第一個事務中修改了這個數據後,第二個事務也修改了這個數據。這樣第一個事務內的修改結果就被丟失,所以稱爲丟失修改。例如:事務1讀取某表中的數據A=20,事務2也讀取A=20,事務1修改A=A-1,事務2也修改A=A-1,最終結果A=19,事務1的修改被丟失。
不可重複讀(Unrepeatableread):sql
指在一個事務內屢次讀同一數據。在這個事務尚未結束時,另外一個事務也訪問該數據。那麼,在第一個事務中的兩次讀數據之間,因爲第二個事務的修改致使第一個事務兩次讀取的數據可能不太同樣。這就發生了在一個事務內兩次讀到的數據是不同的狀況,所以稱爲不可重複讀。
幻讀(Phantom read):數據庫
幻讀與不可重複讀相似。它發生在一個事務(T1)讀取了幾行數據,接着另外一個併發事務(T2)插入了一些數據時。在隨後的查詢中,第一個事務(T1)就會發現多了一些本來不存在的記錄,就好像發生了幻覺同樣,因此稱爲幻讀。
不可重複度和幻讀區別:併發
不可重複讀的重點是修改,幻讀的重點在於新增或者刪除。 例1(一樣的條件, 你讀取過的數據, 再次讀取出來發現值不同了 ):事務1中的A先生讀取本身的工資爲 1000的操做還沒完成,事務2中的B先生就修改了A的工資爲2000,導 致A再讀本身的工資時工資變爲 2000;這就是不可重複讀。 例2(一樣的條件, 第1次和第2次讀出來的記錄數不同 ):假某工資單表中工資大於3000的有4人,事務1讀取了全部工資大於3000的人,共查到4條記錄,這時事務2 又插入了一條工資大於3000的記錄,事務1再次讀取時查到的記錄就變爲了5條,這樣就致使了幻讀。
SQL 標準定義了四個隔離級別:分佈式
隔離級別 | 髒讀 | 不可重複讀 | 幻影讀 |
---|---|---|---|
READ-UNCOMMITTED | √ | √ | √ |
READ-COMMITTED | × | √ | √ |
REPEATABLE-READ | × | × | √ |
SERIALIZABLE | × | × | × |
MySQL InnoDB 存儲引擎的默認支持的隔離級別是 **REPEATABLE-READ(可重讀)**。 咱們能夠經過 "`SELECT @@tx_isolation; `" 命令來查看 mysql> SELECT @@tx_isolation; +-----------------+ | @@tx_isolation | +-----------------+ | REPEATABLE-READ | +-----------------+
這裏須要注意的是:性能
與 **SQL** 標準不一樣的地方在於**InnoDB** 存儲引擎在 **REPEATABLE-READ(可重讀)**事務隔離級別下使用的是**Next-Key Lock** 鎖算法,所以能夠避免幻讀的產生,這與其餘數據庫系統(如 **SQL Server**)是不一樣的。因此說**InnoDB** 存儲引擎的默認支持的隔離級別是 **REPEATABLE-READ(可重讀)** 已經能夠徹底保證事務的隔離性要求,即達到了 SQL標準的**SERIALIZABLE(可串行化)**隔離級別。 由於隔離級別越低,事務請求的鎖越少,因此大部分數據庫系統的隔離級別都是**READ-COMMITTED(讀取提交內容):**,可是你要知道的是**InnoDB** 存儲引擎默認使用 **REPEATABLE-READ**(可重讀)並不會有任何性能損失。 InnoDB 存儲引擎在 **分佈式事務** 的狀況下通常會用到**SERIALIZABLE(可串行化)**隔離級別。