数据库中的事务讲解
數據庫的事務:一系列數據處理(增刪改查)操作的單元,是由一系列預編譯的執行指令組成
在數據中,對于事務的處理是放在線程處理的任務隊列中,當線程由于時間片的分配,切換回來的時候,事務還是會接著之前的步驟執行下去。
事務和事務之前是放在同一個或者不同的線程隊列中的,因此每一個事務之間是獨立的,互斥的。
對于數據庫對事務sql 腳本預處理之后(預編譯),會增加事務的逆向處理操作,防止事務操作失敗之后,可以反向的執行回滾。
數據庫事務的四個特性:
ACID
1. 原子性(Atomicity)
事務的原子性是指事務必須是一個原子的操作序列單元。事務中包含的各項操作在一次執行過程中,只允許出現兩種狀態之一。
全部執行成功
全部執行失敗
任何一項操作都會導致整個事務的失敗,同時其它已經被執行的操作都將被撤銷并回滾,只有所有的操作全部成功,整個事務才算是成功完成。
2. 一致性(Consistency)
事務的一致性是指事務的執行不能破壞數據庫數據的完整性和一致性,一個事務在執行之前和執行之后,數據庫都必須處以一致性狀態。
比如:如果從A賬戶轉賬到B賬戶,不可能因為A賬戶扣了錢,而B賬戶沒有加錢。
3. 隔離性(Isolation)
事務的隔離性是指在并發環境中,并發的事務是互相隔離的,一個事務的執行不能被其它事務干擾。也就是說,不同的事務并發操作相同的數據時,每個事務都有各自完整的數據空間。
一個事務內部的操作及使用的數據對其它并發事務是隔離的,并發執行的各個事務是不能互相干擾的。
隔離性分4個級別,下面會介紹。
4. 持久性(Duration)
事務的持久性是指事務一旦提交后,數據庫中的數據必須被永久的保存下來。即使服務器系統崩潰或服務器宕機等故障。只要數據庫重新啟動,那么一定能夠將其恢復到事務成功結束后的狀態。
-------------------------------------------------------------------------------------------------------------------------------------------------------
數據庫事務是有讀事務和寫事務區分的,那么數據庫對于這兩類的事務會做區分的,也是在分配任務的時候,會做排序,線程會做同步。
比如說對同一個表操作的時候,數據庫會對讀操作的事務放在寫操作的事務后面,保證事務的可重復讀(防止藏獨問題,不可重復讀問題)。
數據庫在分配寫操作的事務線程的時候,會限制讀事務的分配(Read committed);但是不會限制寫事務,如:在已經剛剛分配的讀事務到具體執行的線程,之后突然寫事務到來了,寫事務也會立即具體的分配的線程并發執行,那么在之前分配的讀事務兩次讀操作可能在寫之前和之后,那么兩次讀就不一樣了。?
所以說保證數據庫事務的讀寫分離并同步很關鍵,讀限制寫,寫也需要限制讀(REPEATABLE_READ)。讀和讀之間無需限制;如果純粹的寫,不涉及寫中加讀條件,那么也無需限制。
?
事務隔離級別
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種事務隔離級別從上往下,級別越高,并發性越差,安全性就越來越高。
一般數據默認級別是讀以提交或可重復讀。
?
?
總結
- 上一篇: 魔兽世界怀旧服冬泉火酒任务在哪里 冬泉火
- 下一篇: go 安装 mysql 链接驱动