1乒融、什么是事務(wù)塔拳?
事務(wù)就是一組原子性的SQL查詢,或者說一個(gè)獨(dú)立的工作單元涛目。如果數(shù)據(jù)庫引擎能夠成功地對(duì)數(shù)據(jù)庫應(yīng)用該組查詢的全部語句秸谢,那么就執(zhí)行該組查詢。如果其中有任何一條語句因?yàn)楸罎⒒蚱渌驘o法執(zhí)行霹肝,那么所有的語句都不會(huì)執(zhí)行估蹄。也就是說,事務(wù)內(nèi)的語句沫换,要么全部執(zhí)行成功臭蚁,要么全部執(zhí)行失敗。
2苗沧、事務(wù)的特性(ACID)
- 原子性(Atomicity): 事務(wù)是最小的執(zhí)行單位刊棕,不允許分割。事務(wù)的原子性確保動(dòng)作要么全部完成待逞,要么完全不起作用甥角;
- 一致性(Consistency): 執(zhí)行事務(wù)前后,數(shù)據(jù)保持一致识樱,例如轉(zhuǎn)賬業(yè)務(wù)中嗤无,無論事務(wù)是否成功震束,轉(zhuǎn)賬者和收款人的總額應(yīng)該是不變的;
- 隔離性(Isolation):通常來說当犯,一個(gè)事務(wù)所做的修改在最終提交以前垢村,對(duì)其它事務(wù)是不可見的;
- 持久性(Durability): 一旦事務(wù)提交嚎卫,則其所做的修改就會(huì)永久保存到數(shù)據(jù)庫中嘉栓。即使數(shù)據(jù)庫發(fā)生故障也不應(yīng)該對(duì)其有任何影響。
2拓诸、并發(fā)事務(wù)帶來的問題
在典型的應(yīng)用程序中侵佃,多個(gè)事務(wù)并發(fā)運(yùn)行,經(jīng)常會(huì)操作相同的數(shù)據(jù)來完成各自的任務(wù)(多個(gè)用戶對(duì)統(tǒng)一數(shù)據(jù)進(jìn)行操作)奠支。并發(fā)雖然是必須的馋辈,但可能會(huì)導(dǎo)致以下的問題。
- 臟讀(Dirty read): 當(dāng)一個(gè)事務(wù)正在訪問數(shù)據(jù)并且對(duì)數(shù)據(jù)進(jìn)行了修改倍谜,而這種修改還沒有提交到數(shù)據(jù)庫中迈螟,這時(shí)另外一個(gè)事務(wù)也訪問了這個(gè)數(shù)據(jù),然后使用了這個(gè)數(shù)據(jù)尔崔。因?yàn)檫@個(gè)數(shù)據(jù)是還沒有提交的數(shù)據(jù)答毫,那么另外一個(gè)事務(wù)讀到的這個(gè)數(shù)據(jù)是“臟數(shù)據(jù)”,依據(jù)“臟數(shù)據(jù)”所做的操作可能是不正確的您旁。
- 丟失修改(Lost to modify): 指在一個(gè)事務(wù)讀取一個(gè)數(shù)據(jù)時(shí)烙常,另外一個(gè)事務(wù)也訪問了該數(shù)據(jù),那么在第一個(gè)事務(wù)中修改了這個(gè)數(shù)據(jù)后鹤盒,第二個(gè)事務(wù)也修改了這個(gè)數(shù)據(jù)。這樣第一個(gè)事務(wù)內(nèi)的修改結(jié)果就被丟失侦副,因此稱為丟失修改侦锯。 例如:事務(wù)1讀取某表中的數(shù)據(jù)A=20,事務(wù)2也讀取A=20秦驯,事務(wù)1修改A=A-1尺碰,事務(wù)2也修改A=A-1,最終結(jié)果A=19译隘,事務(wù)1的修改被丟失亲桥。
- 不可重復(fù)讀(Unrepeatableread) : 指在一個(gè)事務(wù)內(nèi)多次讀同一數(shù)據(jù)。在這個(gè)事務(wù)還沒有結(jié)束時(shí)固耘,另一個(gè)事務(wù)也訪問該數(shù)據(jù)题篷。那么,在第一個(gè)事務(wù)中的兩次讀數(shù)據(jù)之間厅目,由于第二個(gè)事務(wù)的修改導(dǎo)致第一個(gè)事務(wù)兩次讀取的數(shù)據(jù)可能不太一樣番枚。這就發(fā)生了在一個(gè)事務(wù)內(nèi)兩次讀到的數(shù)據(jù)是不一樣的情況法严,因此稱為不可重復(fù)讀。
-
幻讀(Phantom read): 幻讀與不可重復(fù)讀類似葫笼。它發(fā)生在一個(gè)事務(wù)(T1)讀取了幾行數(shù)據(jù)深啤,接著另一個(gè)并發(fā)事務(wù)(T2)插入了一些數(shù)據(jù)時(shí)。在隨后的查詢中路星,第一個(gè)事務(wù)(T1)就會(huì)發(fā)現(xiàn)多了一些原本不存在的記錄溯街,就好像發(fā)生了幻覺一樣,所以稱為幻讀洋丐。
不可重復(fù)度和幻讀區(qū)別:不可重復(fù)讀的重點(diǎn)是修改呈昔,幻讀的重點(diǎn)在于新增或者刪除。
3垫挨、事務(wù)的隔離級(jí)別
隔離性其實(shí)比想象的要復(fù)雜韩肝。在SQL標(biāo)準(zhǔn)中定義了四種隔離級(jí)別,每一種級(jí)別都規(guī)定了一個(gè)事務(wù)中所做的修改九榔,哪些在事務(wù)內(nèi)和事務(wù)間是可見的哀峻,哪些是不可見的。較低級(jí)別的隔離通痴懿矗可以執(zhí)行更高的并發(fā)剩蟀,系統(tǒng)的開銷也更低。
- READ UNCOMMITTED(讀取未提交): 最低的隔離級(jí)別切威,允許讀取尚未提交的數(shù)據(jù)變更育特,可能會(huì)導(dǎo)致臟讀、幻讀或不可重復(fù)讀先朦。
- READ COMMITTED(讀取已提交): 允許讀取并發(fā)事務(wù)已經(jīng)提交的數(shù)據(jù)缰冤,可以阻止臟讀,但是不可重復(fù)讀或幻讀仍有可能發(fā)生喳魏。
-
REPEATABLE READ(可重復(fù)讀): 對(duì)同一字段的多次讀取結(jié)果都是一致的棉浸,除非數(shù)據(jù)是被本身事務(wù)自己所修改,可以阻止臟讀和不可重復(fù)讀刺彩,但幻讀仍有可能發(fā)生迷郑。InnoDB存儲(chǔ)引擎通過多版本并發(fā)控制協(xié)議(MVCC,Multivision Concurrency Control)解決了幻讀的問題。
可重復(fù)讀是MySQL的默認(rèn)事務(wù)隔離級(jí)別创倔。 - SERIALIZABLE(可串行化): 最高的隔離級(jí)別嗡害,完全服從ACID的隔離級(jí)別。所有的事務(wù)依次逐個(gè)執(zhí)行畦攘,這樣事務(wù)之間就完全不可能產(chǎn)生干擾霸妹,也就是說,該級(jí)別可以防止臟讀念搬、不可重復(fù)讀以及幻讀抑堡。