数据库事务详解
概述
事務(Transaction)是由一系列對系統中數據進行訪問與更新的操作所組成的一個程序執行邏輯單元。
* ACID
事務具有4個基本特征,分別是:原子性(Atomicity)、一致性(Consistency)、隔離性(Isolation)、持久性(Duration),簡稱ACID。
隔離級別
ACID這4個特征中,最難理解的是隔離性。在標準SQL規范中,定義了4個事務隔離級別,不同的隔離級別對事務的處理不同。4個隔離級別分別是:讀未提及(READ_UNCOMMITTED)、讀已提交(READ_COMMITTED)、可重復讀(REPEATABLE_READ)、順序讀(SERIALIZABLE)。事務并發引起的問題
數據庫在不同的隔離性級別下并發訪問可能會出現以下幾種問題:臟讀(Dirty Read)、不可重復讀(Unrepeatable Read)、幻讀(Phantom Read)。
事務的思維導圖
ACID
1. 原子性(Atomicity)
事務的原子性是指事務必須是一個原子的操作序列單元。事務中包含的各項操作在一次執行過程中,只允許出現兩種狀態之一。
* 全部執行成功
* 全部執行失敗
任何一項操作都會導致整個事務的失敗,同時其它已經被執行的操作都將被撤銷并回滾,只有所有的操作全部成功,整個事務才算是成功完成。
2. 一致性(Consistency)
事務的一致性是指事務的執行不能破壞數據庫數據的完整性和一致性,一個事務在執行之前和執行之后,數據庫都必須處以一致性狀態。
比如:如果從A賬戶轉賬到B賬戶,不可能因為A賬戶扣了錢,而B賬戶沒有加錢。
3. 隔離性(Isolation)
事務的隔離性是指在并發環境中,并發的事務是互相隔離的,一個事務的執行不能被其它事務干擾。也就是說,不同的事務并發操作相同的數據時,每個事務都有各自完整的數據空間。
一個事務內部的操作及使用的數據對其它并發事務是隔離的,并發執行的各個事務是不能互相干擾的。
隔離性分4個級別,下面會介紹。
4. 持久性(Duration)
事務的持久性是指事務一旦提交后,數據庫中的數據必須被永久的保存下來。即使服務器系統崩潰或服務器宕機等故障。只要數據庫重新啟動,那么一定能夠將其恢復到事務成功結束后的狀態。
事務隔離級別
1. 讀未提及(READ_UNCOMMITTED)
讀未提及,該隔離級別允許臟讀取,其隔離級別是最低的。換句話說,如果一個事務正在處理某一數據,并對其進行了更新,但同時尚未完成事務,因此還沒有提交事務;而以此同時,允許另一個事務也能夠訪問該數據。
臟讀示例:
在事務A和事務B同時執行時可能會出現如下場景:
| T1 | 開始事務 | —— |
| T2 | —— | 開始事務 |
| T3 | —— | 查詢余額(1000元) |
| T4 | —— | 取出1000元(余額0元) |
| T5 | 查詢余額(0元) | —— |
| T6 | —— | 撤銷事務(余額恢復1000元) |
| T7 | 存入500元(余額500元) | —— |
| T8 | 提交事務 | —— |
余額應該為1500元才對。請看T5時間點,事務A此時查詢的余額為0,這個數據就是臟數據,他是事務B造成的,很明顯是事務沒有進行隔離造成的。
2. 讀已提交(READ_COMMITTED)
讀已提交是不同的時候執行的時候只能獲取到已經提交的數據。
這樣就不會出現上面的臟讀的情況了。
不可重復讀示例
可是解決了臟讀問題,但是還是解決不了可重復讀問題。
| T1 | 開始事務 | —— |
| T2 | —— | 開始事務 |
| T3 | —— | 查詢余額(1000元) |
| T4 | 查詢余額(1000元) | —— |
| T5 | —— | 取出1000元(余額0元) |
| T6 | —— | 提交事務 |
| T7 | 查詢余額(0元) | —— |
| T8 | 提交事務 | —— |
事務A其實除了查詢兩次以外,其它什么事情都沒做,結果錢就從1000編程0了,這就是不可重復讀的問題。
3. 可重復讀(REPEATABLE_READ)
可重復讀就是保證在事務處理過程中,多次讀取同一個數據時,該數據的值和事務開始時刻是一致的。因此該事務級別進制了不可重復讀取和臟讀,但是有可能出現幻讀的數據。
幻讀
幻讀就是指同樣的事務操作,在前后兩個時間段內執行對同一個數據項的讀取,可能出現不一致的結果。
| T1 | 開始事務 | —— |
| T2 | —— | 開始事務 |
| T3 | 統計總存款(1000元) | —— |
| T4 | —— | 存入100元 |
| T5 | —— | 提交事務 |
| T6 | 提交總存款(10100) | —— |
| T7 | 提交事務 | —— |
銀行工作人員在一個事務中多次統計總存款時看到結果不一樣。如果要解決幻讀,那只能使用順序讀了。
4. 順序讀(SERIALIZABLE)
順序讀是最嚴格的事務隔離級別。它要求所有的事務排隊順序執行,即事務只能一個接一個地處理,不能并發。
事務隔離級別對比
| 讀未提及(READ_UNCOMMITTED) | 允許 | 允許 | 允許 |
| 讀已提交(READ_COMMITTED) | 禁止 | 允許 | 允許 |
| 可重復讀(REPEATABLE_READ) | 禁止 | 禁止 | 允許 |
| 順序讀(SERIALIZABLE) | 禁止 | 禁止 | 禁止 |
4種事務隔離級別從上往下,級別越高,并發性越差,安全性就越來越高。
一般數據默認級別是讀以提交或可重復讀。
想了解更多精彩內容請關注我的公眾號
本人簡書blog地址:http://www.jianshu.com/u/1f0067e24ff8????
點擊這里快速進入簡書
GIT地址:http://git.oschina.net/brucekankan/
點擊這里快速進入GIT
總結
- 上一篇: 聚簇索引和二级索引
- 下一篇: window 查找 java 进程中占用