提到MySQL,相信大家一定都會(huì)想存儲(chǔ)引擎躬窜,想到存儲(chǔ)引擎浇垦,就一定會(huì)想到InnoDB,而提到InnoDB荣挨,就會(huì)想到事務(wù)男韧,而提到事務(wù),肯定會(huì)想到ACID(Atomicity默垄、Consistency此虑、Isolation、Durability口锭,即原子性朦前、一致性、隔離性鹃操、持久性)韭寸,這里就來總結(jié)下我所認(rèn)識(shí)的I,即事務(wù)隔離荆隘。
事務(wù)隔離的概念和事務(wù)同時(shí)執(zhí)行的問題
首先恩伺,我們要知道事務(wù)隔離是為什么出現(xiàn)的,一個(gè)技術(shù)的出現(xiàn)就是為了要解決問題椰拒,而事務(wù)隔離的出現(xiàn)就是為了解決多個(gè)事務(wù)同時(shí)執(zhí)行時(shí)會(huì)出現(xiàn)的三個(gè)問題:臟讀晶渠,不可重復(fù)讀凰荚,幻讀。這里先解釋下這三個(gè)問題的概念褒脯。
1.臟讀:事務(wù)A讀取了事務(wù)B更新的數(shù)據(jù)浇揩,然后B回滾事務(wù),A讀取到的就是臟數(shù)據(jù)憨颠。
2.不可重復(fù)讀:事務(wù)A多次讀取同一數(shù)據(jù)胳徽,事務(wù)B在事務(wù)A多次讀取的過程中,對(duì)數(shù)據(jù)做了更新并提交爽彤,導(dǎo)致事務(wù)A多次讀取同一數(shù)據(jù)時(shí)养盗,結(jié)果不一致。
3.幻讀:事務(wù)A將數(shù)據(jù)庫中所有學(xué)生的成績(jī)從具體分?jǐn)?shù)改為ABCDE等級(jí)适篙,但是事務(wù)B就在這個(gè)時(shí)候插入了一條具體分?jǐn)?shù)的記錄往核,當(dāng)A改結(jié)束后發(fā)現(xiàn)還有一條記錄沒有改過來,就好像發(fā)生了幻覺一樣嚷节。
事務(wù)的隔離級(jí)別為:讀未提交(read uncommitted)聂儒、讀提交(read committed)、可重復(fù)讀(repeatable read)和串行化(serializable )
讀未提交是指硫痰,一個(gè)事務(wù)還沒提交時(shí)衩婚,它做的變更就能被別的事務(wù)看到。
讀提交是指效斑,一個(gè)事務(wù)提交之后非春,它做的變更才會(huì)被其他事務(wù)看到。
可重復(fù)讀是指缓屠,一個(gè)事務(wù)執(zhí)行過程中看到的數(shù)據(jù)奇昙,總是跟這個(gè)事務(wù)在啟動(dòng)時(shí)看到的數(shù)據(jù)是一致的。當(dāng)然在可重復(fù)讀隔離級(jí)別下敌完,未提交變更對(duì)其他事務(wù)也是不可見的储耐。
串行化,顧名思義是對(duì)于同一行記錄滨溉,“寫”會(huì)加“寫鎖”什湘,“讀”會(huì)加“讀鎖”。當(dāng)出現(xiàn)讀寫鎖沖突的時(shí)候业踏,后訪問的事務(wù)必須等前一個(gè)事務(wù)執(zhí)行完成禽炬,才能繼續(xù)執(zhí)行。
這里概念不理解沒關(guān)系勤家,下面我會(huì)用一個(gè)例子來說明事務(wù)隔離和這幾個(gè)概念。
隔離級(jí)別對(duì)應(yīng)解決的問題
事務(wù)隔離級(jí)別 | 臟讀 | 不可重復(fù)讀 | 幻讀 |
---|---|---|---|
讀未提交(read-uncommitten) | 是 | 是 | 是 |
讀提交(read-committen) | 否 | 是 | 是 |
可重復(fù)讀(repeatable-read) | 否 | 否 | 是 |
串行化(serilaizable) | 否 | 否 | 否 |
MySQL的默認(rèn)隔離級(jí)別是RR柳恐。
舉個(gè)栗子??
使用如下語句建表
mysql> create table T(c int) engine=InnoDB;
insert into T(c) values(1);
在不同的隔離級(jí)別中我們來看看v1伐脖,v2热幔,v3的值分別是什么?
若隔離級(jí)別是讀未提交(RU)讼庇,v1的值是2绎巨,因?yàn)樵赗U中,B未提交的值也被A所看到了蠕啄,所以:v2的值是2场勤,v3的值是2
若隔離級(jí)別是讀提交(RC),v1的值是1歼跟,事務(wù)B在提交后的更新能被A看到和媳,所以v2的值是2,v3的值是2
若隔離級(jí)別是可重復(fù)讀(RR)哈街,v1的值是1留瞳,v2的值是1,這里之所以是1骚秦,是應(yīng)為在RR中需要遵循:事務(wù)在執(zhí)行期間看到的數(shù)據(jù)前后必須是一致的她倘,v3的值是2。這里插上一句作箍,如果將查詢得到值v2改成:將該數(shù)據(jù)的值+1硬梁,查詢得到值v2,那么v2的值是多少呢胞得?v2的值是3靶溜,這里為什么沒有變成2而變成了3呢?是應(yīng)為計(jì)算v2的時(shí)候用的是2來加一的懒震,所以是3罩息。數(shù)據(jù)的一致性倒是沒有被破壞。RR的隔離級(jí)別下使用了MVCC(多版本并發(fā)控制)機(jī)制个扰,select操作不會(huì)更新版本號(hào)瓷炮,是快照讀(歷史版本);insert递宅、update和delete會(huì)更新版本號(hào)娘香,是當(dāng)前讀(當(dāng)前版本)。這里不展開了办龄,以后有時(shí)間可以專門針對(duì)RR來展開寫一篇總結(jié)博客烘绽。
若隔離級(jí)別是串行化,在B更新值的時(shí)候俐填,會(huì)被鎖住安接,直到事務(wù)A提交,B事務(wù)才能繼續(xù)執(zhí)行英融,所以v1的值是1盏檐,v2的值是1歇式,v3的值是2
總結(jié)
從這里我們可以看出每個(gè)隔離級(jí)別都有自己的使用場(chǎng)景,但是隔離級(jí)別越高胡野,執(zhí)行的效率就越低材失,所以要根據(jù)自己的業(yè)務(wù)場(chǎng)景來選擇合適的隔離級(jí)別。