前言
大家好,我是程序蛇玩編程。
Mysql中事務大家不陌生吧,事務就是要保證一組數據庫操作,要么全部成功,要么全部失敗。那它具有哪些特性,如何實現的呢?接著往下看。
正文
事務的特性:
事務的基本特性主要為四種,原子性,一致性,隔離性,持久性,下面一一介紹:
1.原子性(Atomicity):事務是數據庫的邏輯工作單位,事務中包含的各操作要么全部成功,要么全部失敗。如果事務中的某個操作失敗,整個事務將回滾(Rollback),撤銷所有已執行的操作,返回到事務開始前的狀態。
2.一致性:一致性狀態是指數據庫中的數據應滿足所有預定義的規則和約束,例如實體完整性、參照完整性等。
3.隔離性:并發執行的事務之間不會相互影響,每個事務都感覺不到其他事務的存在。事務的隔離性有不同的級別,包括讀未提交(Read Uncommitted)、讀已提交(Read Committed)、可重復讀(Repeatable Read)和串行化(Serializable)。
4.持久性:一旦事務被提交(Commit),它對數據庫的修改就是永久性的,即使系統發生故障也不會丟失。
今天主要向大家介紹隔離性,他能解決什么問題呢? 假如事務沒有隔離性的話,多個事務同時執行的時候就可能出現臟讀、不可重復讀、幻讀的問題,于是就誕生了隔離性,它有如上述的四種隔離級別。
1.讀未提交是指,一個事務可以讀取到其他事務未提交的數據。
2.讀提交是指,一個事務只能讀取到其他事務已經提交的數據。
3.可重復讀是指,它確保了一個事務在執行期間可以多次讀取相同的數據集,而不會看到其他并發事務對這些數據所做的更改。
4.串行化,顧名思義是對于同一行記錄,“寫”會加“寫鎖”,“讀”會加“讀鎖”。當出現讀寫鎖沖突的時候,后訪問的事務必須等前一個事務執行完成,才能繼續執行。
其中"讀提交"和"可重復讀"較難理解,我舉了一個例子如下圖所示,假設數據表S只有一列,一行的值為1,兩個事務按照時間順序執行。
我們來看看事務A在不同的隔離級別下,分別返回什么結果。
若隔離級別是"讀提交",則a1是1,a2是2,事務B的更改在提交后才能被事務A看到,所以a3也是2。
若隔離級別是"可重復讀",則a1,a2都是1,a3才是2,之所以a2是1,遵循的就是這個要求:事務在執行期間看到的數據前后必須是一致的。
那如何做到事務看還是看不見的呢?
數據庫里面會創建一個視圖,訪問的時候以視圖的邏輯結果為準。在“可重復讀”隔離級別下,這個視圖是在事務啟動時創建的,整個事務存在期間都用這個視圖。而在“讀提交”隔離級別下,這個視圖是在每個 SQL 語句開始執行的時候創建的。這里需要注意的是,“讀未提交”隔離級別下直接返回記錄上的最新值,沒有視圖概念;而“串行化”隔離級別下直接用加鎖的方式來避免并行訪問。
事務隔離的實現:
在 MySQL 中,實際上每條記錄在更新的時候都會同時記錄一條回滾操作。記錄上的最新值,通過回滾操作,都可以得到前一個狀態的值。
我們假設一個值從10被按順序改成了11,12,13,在回滾日志(undolog)中有如下記錄:
當前值是 13,但是在查詢這條記錄的時候,不同時刻啟動的事務會有不同的 視圖。視圖 A、B、C 里面,這一個記錄的值分別是 10、11、13,同一條記錄在系統中可以存在多個版本,這就是數據庫的多版本并發控制(MVCC)。
今日小結
今天簡單給大家介紹了事務的四大特性,并用一個例子說明了不同隔離級別下事務查詢返回的結果,最后述說了事務隔離的實現,講到了回滾日志以及視圖,下一期我們再會。很多八股文內容合集就來這哈。