事務
事務指的是滿足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級別。
推薦學習:MySQL教學
以上是淺談資料庫交易和隔離等級的詳細內容。更多資訊請關注PHP中文網其他相關文章!