事務是由一組SQL語句組成的邏輯處理單元,是知足 ACID 特性的一組操做,能夠經過 Commit 提交一個事務,也可使用 Rollback 進行回滾。事務具備如下4個屬性,一般簡稱爲事務的ACID屬性:java
MySQL 默認採用 自動提交模式。也就是說,若是不顯式使用 START TRANSACTION 語句來開始一個事務,那麼每一個查詢都會被當作一個事務自動提交。
這幾個特性不是一種平級關係:程序員
T1 和 T2 兩個事務都對一個數據進行修改,T1 先修改,T2 隨後修改,T2 的修改覆蓋了 T1 的修改。數據庫
例如,兩個程序員修改同一java文件。每程序員獨立地更改其副本,而後保存更改後的副本,這樣就覆蓋了原始文檔。最後保存其更改副本的編輯人員覆蓋前一個程序員所作的更改。數據結構
若是在一個程序員完成並提交事務以前,另外一個程序員不能訪問同一文件,則可避免此問題。併發
一句話:事務B讀取到了事務A已修改但還沒有提交的的數據,還在這個數據基礎上作了操做。此時,若是A事務回滾Rollback,B讀取的數據無效,不符合一致性要求。性能
解決辦法: 把數據庫的事務隔離級別調整到 READ_COMMITTED學習
T1 修改一個數據,T2 隨後讀取這個數據。若是 T1 撤銷了此次修改,那麼 T2 讀取的數據是髒數據。spa
在一個事務內,屢次讀同一個數據。在這個事務尚未結束時,另外一個事務也訪問該同一數據。那麼,在第一個事務的兩次讀數據之間。因爲第二個事務的修改,那麼第一個事務讀到的數據可能不同,這樣就發生了在一個事務內兩次讀到的數據是不同的,所以稱爲不可重複讀,即原始讀取不可重複。3d
一句話:一個事務範圍內兩個相同的查詢卻返回了不一樣數據。日誌
同時操做,事務1分別讀取事務2操做時和提交後的數據,讀取的記錄內容不一致。不可重複讀是指在同一個事務內,兩個相同的查詢返回了不一樣的結果。
解決辦法: 若是隻有在修改事務徹底提交以後才能夠讀取數據,則能夠避免該問題。把數據庫的事務隔離級別調整到REPEATABLE_READ
T2 讀取一個數據,T1 對該數據作了修改。若是 T2 再次讀取這個數據,此時讀取的結果和第一次讀取的結果不一樣。
一個事務T1按相同的查詢條件從新讀取之前檢索過的數據,卻發現其餘事務T2插入了知足其查詢條件的新數據,這種現象就稱爲「幻讀」。(和可重複讀相似,可是事務 T2 的數據操做僅僅是插入和刪除,不是修改數據,讀取的記錄數量先後不一致)
一句話:事務A 讀取到了事務B提交的新增數據,不符合隔離性。
解決辦法: 若是在操做事務完成數據處理以前,任何其餘事務都不能夠添加新數據,則可避免該問題。把數據庫的事務隔離級別調整到 SERIALIZABLE_READ。
T1 讀取某個範圍的數據,T2 在這個範圍內插入新的數據,T1 再次讀取這個範圍的數據,此時讀取的結果和和第一次讀取的結果不一樣。
"髒讀"、"不可重複讀"和"幻讀",其實都是數據庫讀一致性問題,必須由數據庫提供必定的事務隔離機制來解決。
數據庫的事務隔離越嚴格,併發反作用越小,但付出的代價也就越大,由於事務隔離實質上就是使事務在必定程度上 「串行化」進行,這顯然與「併發」是矛盾的。同時,不一樣的應用對讀一致性和事務隔離程度的要求也是不一樣的,好比許多應用對「不可重複讀」和「幻讀」並不敏感,可能更關心數據併發訪問的能力。
MYSQL常看當前數據庫的事務隔離級別:show variables like 'tx_isolation'
;
最低的隔離等級,容許其餘事務看到沒有提交的數據,會致使髒讀。
被讀取的數據能夠被其餘事務修改,這樣可能致使不可重複讀。也就是說,事務讀取的時候獲取讀鎖,可是在讀完以後當即釋放(不須要等事務結束),而寫鎖則是事務提交以後才釋放,釋放讀鎖以後,就可能被其餘事務修改數據。該等級也是 SQL Server 默認的隔離等級。
全部被 Select 獲取的數據都不能被修改,這樣就能夠避免一個事務先後讀取數據不一致的狀況。可是卻沒有辦法控制幻讀,由於這個時候其餘事務不能更改所選的數據,可是能夠增長數據,即前一個事務有讀鎖可是沒有範圍鎖,爲何叫作可重複讀等級呢?那是由於該等級解決了下面的不可重複讀問題。(引伸:如今主流數據庫都使用 MVCC 併發控制,使用以後RR(可重複讀)隔離級別下是不會出現幻讀的現象。)
MYSQL默認是REPEATABLE-READ
。
全部事務一個接着一個的執行,這樣能夠避免幻讀 (phantom read),對於基於鎖來實現併發控制的數據庫來講,串行化要求在執行範圍查詢的時候,須要獲取範圍鎖,若是不是基於鎖實現併發控制的數據庫,則檢查到有違反串行操做的事務時,需回滾該事務。
四個級別逐漸加強,每一個級別解決一個問題,事務級別越高,性能越差,大多數環境(Read committed 就能夠用了)
隔離級別 | 讀數據一致性 | 髒讀 | 不可重複讀 | 幻影讀 |
---|---|---|---|---|
未提交讀 | 最低級別 | √ | √ | √ |
提交讀 | 語句級 | × | √ | √ |
可重複讀 | 事務級 | × | × | √ |
可串行讀 | 最高級別,事務級 | × | × | × |