深入解析MySQL 事務

事務指邏輯上的一組操作,組成這組操作的各個單元,要麼全部成功,要麼全部失敗。

事務的四大特性 ( ACID )

原子性(Atomicity):一個事物是一個不可分割的單位,要麼全都執行,要麼都不執行;

一致性(Consistency):事務執行前後,數據處於合法的狀態;

持久性(Isolation):事務執行完後,數據的修改是持久的,不會因為其他操作或故障而對其產生影響;

隔離性(Durability):多個事務並發執行的,事務之間不互相幹擾。

假如事物的一個操作整體(動作A,B),動作A,執行完瞭,動作B,執行到一半,執行過程出錯,這時怎麼辦?有回滾機制,有個日志會記錄這些操作,記錄數據修改前和數據修改後的值。

臟讀

事務A正在修改數據(但是沒有提交),事務B就讀取瞭這裡的數據,此時事務B讀取的操作稱為臟讀。 解決辦法:給寫操作加鎖,當事務A在寫數據的時候,事務B無法讀取。

不可重復讀

事務A修改數據之後提交瞭數據“name=L”,然後事務B就讀取數據,但是此時A覺得修改的數據不滿意“name=H”,繼續修改提交瞭,此時事務B再次讀取,發現,啊,怎麼數據不一樣瞭。這就是不可重復讀的問題。 解決辦法:給寫操作加鎖的同時,給讀操作也加鎖,當事務A在寫的時候,事務B不可以讀,事物B在讀的時候,事物A也不可以寫。

幻讀

雖然已經給寫操作加鎖,和讀操作加鎖,但是會有種情況,事務B在讀的時候,事務A無法修改name,但是事務A可以再寫一個age,當事務B再次讀取數據的時候發現,咦,怎麼多瞭條數據。 解決辦法:隻能嚴格的串行化執行。(並發程度最低,效率也最低,但是數據的可靠性最高)

這裡很容易搞混不可重復讀和幻讀。其實隻需要理解,不可重復讀是修改數據,數據的條數不變;幻讀是增加或者刪除數據,數據的內容不變,條數發生改變。

MySQL的隔離級別

讀未提交(read-uncommitted):會有臟讀,不可重復讀,幻讀問題 不可重復讀(read-committed):會有不可重復讀,幻讀問題 可重復讀(repeatable-read):會有幻讀問題 串行化 (serializable):解決這三個問題

事務的隔離級別並不是越高越好,但事務的隔離級別越高,那麼並發性就越低,效率越低,數據的可靠性就會越高。

MySQL8開始,用SELECT@@GLOBAL.transaction_isolation,@@transaction_isolation;查詢隔離級別(這裡是是MySQL5)

這裡我們可以看到MySQL的全局隔離級別和當前會話隔離級別皆是REPEATABLE一READ(可重復讀),不同的數據庫有不同的默認隔離級別,而且我們也可以自行修改它。

通過如下命令可以修改隔離級別(建議在修改時修改當前 session 隔離級別即可,不用修改全局的隔離級別):

SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

註意,如果隻是修改瞭當前 session 的隔離級別,則換一個 session 之後,隔離級別又會恢復到默認的隔離級別,所以我們測試時,修改當前 session 的隔離級別即可。

到此這篇關於深入解析MySQL 事務的文章就介紹到這瞭,更多相關MySQL 事務內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: