一、什么是事務?
事務(Transaction)是訪問並可能更新數據庫中各項數據項的一個程序執行單元(unit)。事務由事務開始(begin transaction)和事務結束(end transaction)之間執行的全體操作組成。
事務是一個不可分割的數據庫操作序列,也是數據庫並發控制的基本單位,其執行的結果必須使數據庫從一種一致性狀態變到另一種一致性狀態。
事務結束有兩種,事務中的步驟全部成功執行時,提交事務。如果其中一個失敗,那么將會發生回滾操作,並且撤銷之前的所有操作。也就是說,事務內的語句,要么全部執行成功,要么全部執行失敗。
事務是恢復和並發控制的基本單位。
事務具有四個特征:原子性、一致性、隔離性和持久性。這四個特征通常稱為ACID。
二、事務的四個特征(ACID)
原子性(Atomicity)
原子性是指事務是一個不可分割的工作單位,整個事務中的所有操作要么全部提交成功,要么全部失敗回滾,對於一個事務來說,不可能只執行其中的一部分操作。
一致性(Consistency)
一致性是指事務必須使數據庫從一個一致性狀態變換到另一個一致性狀態。
也就是說事務前后數據的完整性必須保持一致。
隔離性(Isolation)
隔離性是指一個事務的執行不能有其他事務的干擾,事務的內部操作和使用數據對其他的並發事務是隔離的,互不干擾。
持久性(Durability)
持久性是指一個事務一旦提交,對數據庫中數據的改變就是永久性的。此時即使數據庫發生故障,修改的數據也不會丟失。接下來其他的操作不會對已經提交了的事務產生影響。
三、什么是臟讀、不可重復讀、幻讀?
臟讀
臟讀是指在一個事務處理過程里讀取了另一個未提交的事務中的數據。
比如在事務 A 修改數據之后提交數據之前,這時另一個事務 B 來讀取數據,如果不加控制,事務 B 讀取到 A 修改過數據,之后 A 又對數據做了修改再提交,則 B 讀到的數據是臟數據,此過程稱為臟讀。
不可重復讀
不可重復讀是指在數據庫訪問中,一個事務范圍內多次查詢卻返回了不同的數據值。這是由於在查詢間隔中,其他事務修改並提交而引起的。
比如事務 T1 讀取某一數據,事務 T2 讀取並修改了該數據,T1 為了對讀取值進行檢驗而再次讀取該數據,便得到了不同的結果。
幻讀
幻讀是指當事務不是獨立執行時發生的一種現象,例如第一個事務對一個表中的數據進行了修改,比如這種修改涉及到表中的全部數據行。同時,第二個事務也修改這個表中的數據,這種修改是向表中插入一行新數據。那么,以后就會發生操作第一個事務的用戶發現表中還有沒有修改的數據行,就好象發生了幻覺一樣。
比如事務 A 在按查詢條件讀取某個范圍的記錄時,事務 B 又在該范圍內插入了新的滿足條件的記錄,當事務 A 再次按條件查詢記錄時,會產生新的滿足條件的記錄。
四、SQL的四個隔離級別
未提交讀(Read Uncommitted)
一個事務能夠讀取到別的事務中沒有提交的更新數據。事務中的修改,即使沒有提交,其他事務也可以看得到。在這種隔離級別下有可能發生臟讀,不可重復讀和幻讀。
提交讀(Read Committed)
事務中的修改只有提交以后才能被其它事務看到。在這種隔離級別下解決了臟讀,但是有可能發生不可重復讀和幻讀。
可重復讀(Repeated Read)
保證了在同一事務中先后執行的多次查詢將返回同一結果,看到的每行的記錄的結果是一致的,不受其他事務的影響。但是這種級別下有可能發生幻讀。
可串行化(Serializable)
不允許事務並發執行,強制事務串行執行。就是在讀取的每一行數據上都加上了鎖,讀寫相互都會阻塞,所以效率很低下。這種隔離級別最高,是最安全的,但是性能最低,不會出現臟讀,不可重復讀,幻讀。
隔離級別 | 臟讀 | 不可重復讀 | 幻讀 |
---|---|---|---|
Read Uncommitted | YES | YES | YES |
Read Committed | NO | YES | YES |
Repeated Read | NO | NO | YES |
Serializable | NO | NO | NO |