1. 程式人生 > >資料庫事務和隔離級別(重點,不可重複讀和可重複度的區別)

資料庫事務和隔離級別(重點,不可重複讀和可重複度的區別)

資料庫事務的四個特性(ACID)

1 、原子性 (Atomicity)
事務是資料庫的邏輯工作單位,事務中包含的各操作要麼都做,要麼都不做
2 、一致性 (Consistency)
事務執行的結果必須是使資料庫從一個一致性狀態變到另一個一致性狀態。因此當資料庫只包含成功事務提交的結果時,就說資料庫處於一致性狀態。如果資料庫系統 執行中發生故障,有些事務尚未完成就被迫中斷,這些未完成事務對資料庫所做的修改有一部分已寫入物理資料庫,這時資料庫就處於一種不正確的狀態,或者說是 不一致的狀態。
3 、隔離性(Isolation)
一個事務的執行不能其它事務干擾。即一個事務內部的操作及使用的資料對其它併發事務是隔離的,併發執行的各個事務之間不能互相干擾。
4 、持續性 (Durability)
也稱永久性,指一個事務一旦提交,它對資料庫中的資料的改變就應該是永久性的。接下來的其它操作或故障不應該對其執行結果有任何影響。

資料庫事務的隔離級別

1、未提交讀(Read uncommitted)
事務中的修改及時沒提交也會被其他事務可見,這樣會產生髒讀,如果事務失敗回滾,則其他事務之前的到的資料則是髒資料。從效能上講,不會別別的事務提高太多,但是極其不安全。

2、讀提交(Read committed)
又可叫不可重複讀,大多數資料庫預設的隔離模式(MySQL不是)。在事務完成提交之前,其他事務看不到該事務的修改結果。執行兩次同樣的查詢可能看到不一樣的結果。

3、重複讀(Repeatable read)
事務A讀取與搜尋條件相匹配的若干行。事務B以插入或刪除行等方式來修改事務A的結果集,然後再提交。事務A再讀取時,卻發現數據發生了變化。造成了幻讀。(MySQL預設的隔離級別)

4、序列化(Serializable)
Serializable是最高的事務隔離級別,同時代價也花費最高,效能很低,一般很少使用,在該級別下,事務順序執行,不僅可以避免髒讀、不可重複讀,還避免了幻像讀。

其中1和4比較好理解,一個不安全,一個安全卻效能較差。一開始我也比較糾結2和3。

讀提交,不可重複讀,個人理解是針對一條記錄,因為T1事務中讀取一條記錄時未加鎖,此時T2事務可以修改該記錄,當T1第一次讀取後,並使用該值做了一些校驗正準備在此讀取做更新操作時,發現數據和之前第一次讀的不一致了。

例如,你在ATM取錢,先查詢了一下餘額發現還有10塊錢,你正準備取出買東西時,10塊錢卻被你女朋友利用網上銀行扣走了,在你查完餘額轉到取錢時,ATM發現餘額不足了。前後兩次你看到的餘額不同,造成了不可重複讀或者虛讀。

可重複讀,在一條記錄上的操作是,不能讀取已由其它事務修改了但是未提交的行,其它任何事務也不能修改在當前事務完成之前由當前事務讀取的資料。但是對於其它事務插入的新行資料,當前事務第二次訪問錶行時會檢索這一新行。因此,這一個隔離級別的設定解決了 Non-Repeatable Reads 不可重複讀取的問題,但是避免不了 Phantom Reads 幻讀。

例如:事務T1在讀取R1和修改R2,此時T2不能夠讀取R2也不能修改R1,這樣T2的操作就不會影響到T1的操作,但是,如果T1中含有一個統計某個範圍內記錄數量的操作,而T2在此時正好在此範圍內插入了一條記錄,則會草成T1的幻讀,即第一次讀此範圍內一共2條資料,而在次讀的時候卻有了3條資料。

個人感覺,兩者的的區別是,讀提交在讀取一條記錄時會出現不可重複讀,而可重複度通過對事務裡面的讀寫操作加鎖,解決了度提交的問題,但是對統計某個範圍內的記錄數量,還是會產生幻讀。