您好,登錄后才能下訂單哦!
這篇文章將為大家詳細講解有關數據庫的事務和隔離等級,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。
事務
事務指的是滿足 ACID 特性的一組操作,可以通過 Commit 提交一個事務,也可以使用 Rollback 進行回滾。
ACID
1.原子性(Atomicity)
事務被視為不可分割的最小單元,事務的所有操作要么全部提交成功,要么全部失敗回滾。回滾可以用回滾日志來實現,回滾日志記錄著事務所執行的修改操作,在回滾時反向執行這些修改操作即可。
2.一致性(Consistency)
一致性是指事務必須使數據庫從一個一致性狀態變換到另一個一致性狀態,也就是說一個事務執行之前和執行之后都必須處于一致性狀態。
拿轉賬來說,假設用戶A和用戶B兩者的錢加起來一共是5000,那么不管A和B之間如何轉賬,轉幾次賬,事務結束后兩個用戶的錢相加起來應該還得是5000,這就是事務的一致性。
3.隔離性(Isolation)
隔離性是當多個用戶并發訪問數據庫時,比如操作同一張表時,數據庫為每一個用戶開啟的事務,不能被其他事務的操作所干擾,多個并發事務之間要相互隔離。
即要達到這么一種效果:對于任意兩個并發的事務T1和T2,在事務T1看來,T2要么在T1開始之前就已經結束,要么在T1結束之后才開始,這樣每個事務都感覺不到有其他事務在并發地執行。
4.持久性(Durability)
持久性是指一個事務一旦被提交了,那么對數據庫中的數據的改變就是永久性的,即便是在數據庫系統遇到故障的情況下也不會丟失提交事務的操作。
并發一致性問題
1.臟讀
臟讀是指在一個事務處理過程里讀取了另一個未提交的事務中的數據。
T1 修改一個數據,T2 隨后讀取這個數據。如果 T1 撤銷了這次修改,那么 T2 讀取的數據是臟數據。
2.不可重復讀
不可重復讀是指在對于數據庫中的某個數據,一個事務范圍內多次查詢卻返回了不同的數據值,這是由于在查詢間隔,被另一個事務修改并提交了。
例如事務T1在讀取某一數據,而事務T2立馬修改了這個數據并且提交事務給數據庫,事務T1再次讀取該數據就得到了不同的結果,發送了不可重復讀。
不可重復讀和臟讀的區別是,臟讀是某一事務讀取了另一個事務未提交的臟數據,而不可重復讀則是讀取了前一事務提交的數據。
3.幻讀
幻讀是事務非獨立執行時發生的一種現象。例如事務T1對一個表中所有的行的某個數據項做了從“1”修改為“2”的操作,這時事務T2又對這個表中插入了一行數據項,而這個數據項的數值還是為“1”并且提交給數據庫。而操作事務T1的用戶如果再查看剛剛修改的數據,會發現還有一行沒有修改,其實這行是從事務T2中添加的,就好像產生幻覺一樣,這就是發生了幻讀。
幻讀和不可重復讀都是讀取了另一條已經提交的事務(這點就臟讀不同),所不同的是不可重復讀查詢的都是同一個數據項,而幻讀針對的是一批數據整體(比如數據的個數)。
T1 讀取某個范圍的數據,T2 在這個范圍內插入新的數據,T1 再次讀取這個范圍的數據,此時讀取的結果和和第一次讀取的結果不同。
MySQL隔離級別
1. Serializable (串行化):強制事務串行執行。
可避免臟讀、不可重復讀、幻讀的發生。
2. Repeatable read (可重復讀):保證在同一個事務中多次讀取同樣數據的結果是一樣的
可避免臟讀、不可重復讀的發生。
3. Read committed (讀已提交):一個事務只能讀取已經提交的事務所做的修改
可避免臟讀的發生。
4. Read uncommitted (讀未提交):事務中的修改,即使沒有提交,對其他事務也是可見的
最低級別,任何情況都無法保證。
隔離級別最高的是Serializable級別,最低的是Read uncommitted級別,級別越高,執行效率就越低。
像Serializable這樣的級別,就是以鎖表的方式(類似于Java多線程中的鎖)使得其他的線程只能在鎖外等待,所以平時選用何種隔離級別應該根據實際情況。
在MySQL數據庫中默認的隔離級別為Repeatable read (可重復讀)。
Oracle數據庫中,只支持 Serializable (串行化) 級別和 Read committed (讀已提交) 這兩種級別,其中默認的為Read committed級別。
關于數據庫的事務和隔離等級就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。