根據(jù)維基百科的定義,一個(gè)數(shù)據(jù)庫事務(wù)通常包含了一個(gè)序列的對(duì)數(shù)據(jù)庫的讀/寫操作。它的存在包含有以下兩個(gè)目的:1)為數(shù)據(jù)庫操作序列提供了一個(gè)從失敗中恢復(fù)到正常狀態(tài)的方法,同時(shí)提供了數(shù)據(jù)庫即使在異常狀態(tài)下仍能保持一致性的方法;2)當(dāng)多個(gè)應(yīng)用程序在并發(fā)訪問數(shù)據(jù)庫時(shí),可以在這些應(yīng)用程序之間提供一個(gè)隔離方法,以防止彼此的操作互相干擾。簡(jiǎn)單來講,事務(wù)的作用至少有兩個(gè):保證數(shù)據(jù)一致性,以及對(duì)數(shù)據(jù)進(jìn)行隔離。這么說大家可能還不太好理解,我們還是舉個(gè)例子說明一下吧。 我們以A向B轉(zhuǎn)賬100塊錢為例,在一筆轉(zhuǎn)賬操作中,至少必須包含2個(gè)操作: 將A的賬戶余額扣除100塊錢(假設(shè)轉(zhuǎn)賬前A的賬戶余額大于100塊錢) 將B的賬戶余額增加100塊錢
如果在轉(zhuǎn)賬的過程中不使用事務(wù),那么有可能會(huì)出現(xiàn)在將A的賬戶扣除100塊錢之后,發(fā)生了不可預(yù)知的異常(比方說服務(wù)器宕機(jī)了),導(dǎo)致沒來得及將B的賬戶增加100塊錢,如此一來,數(shù)據(jù)庫就產(chǎn)生了數(shù)據(jù)不一致的情況,即A的賬戶扣了100塊錢,但是B的賬戶并沒有相應(yīng)地增加100塊錢,也就是說有100塊錢“不翼而飛”了。而如果將這2個(gè)操作放在一個(gè)事務(wù)里執(zhí)行的話,由于事務(wù)中的操作要么全部執(zhí)行,要么全部不執(zhí)行,所以可以保證數(shù)據(jù)一致性。這就是在數(shù)據(jù)一致性要求比較高的場(chǎng)景下使用事務(wù)的好處。 事務(wù)的特性主要有4個(gè):原子性,一致性,隔離性與持久性,也叫做ACID。 原子性,指的是一個(gè)事務(wù)必須被視為一個(gè)不可分割的最小工作單元,整個(gè)事務(wù)中的操作要么全部提交成功,要么全部失敗回滾,也就是說不可能只執(zhí)行事務(wù)中的部分操作,這就是事務(wù)的原子性。 一致性,指的是事務(wù)應(yīng)確保數(shù)據(jù)庫的狀態(tài)從一個(gè)一致狀態(tài)轉(zhuǎn)變?yōu)榱硪粋€(gè)一致狀態(tài)。以上述轉(zhuǎn)賬的例子為例,轉(zhuǎn)賬后A的賬戶減少100塊錢,B的賬戶增加100塊錢是滿足數(shù)據(jù)一致性的,事務(wù)可以保證事務(wù)成功提交之后數(shù)據(jù)庫轉(zhuǎn)化為這個(gè)狀態(tài),如果事務(wù)失敗回滾了,則還是保持最初的一致性狀態(tài),而不會(huì)出現(xiàn)上述的A的賬戶減少100塊錢,B的賬戶沒有變化的不一致的中間狀態(tài)。 隔離性,指的是多個(gè)事務(wù)并發(fā)執(zhí)行時(shí),一個(gè)事務(wù)的執(zhí)行不應(yīng)影響其他事務(wù)的執(zhí)行。比如當(dāng)A向B轉(zhuǎn)賬的過程中,B也可以向A轉(zhuǎn)賬,這2個(gè)事務(wù)互不影響,而且通常來講也是互不可見的(注意,是通常來講“不可見”,后續(xù)講到事務(wù)隔離級(jí)別的時(shí)候再詳述)。 持久性,指的是已被提交的事務(wù)對(duì)數(shù)據(jù)庫的修改應(yīng)該被永久保存在數(shù)據(jù)庫中。這個(gè)比較好理解,就是說已成功提交的事務(wù)會(huì)被永久地保存下來。
前文說到,事務(wù)具有隔離性,而且通常來講,不同事務(wù)之間是不可見的,然而現(xiàn)實(shí)中的事務(wù)隔離性并不都是不可見的,實(shí)際上,SQL標(biāo)準(zhǔn)定義了4種事務(wù)隔離級(jí)別:讀未提交,讀已提交,可重復(fù)讀,串行化,下文將逐一講解。 讀未提交,指的是事務(wù)中未提交的修改,對(duì)于其他事務(wù)而言是可見的,這是隔離性最低的一種級(jí)別了。在這種隔離級(jí)別下,會(huì)出現(xiàn)“臟讀”的情況。所謂“臟讀”指的是讀取到了其他事務(wù)未提交的數(shù)據(jù)。我們以2個(gè)事務(wù)同時(shí)進(jìn)行為例,因?yàn)槭聞?wù)A可以讀到事務(wù)B的未提交的修改數(shù)據(jù),假如說事務(wù)B在事務(wù)A結(jié)束之前因?yàn)榘l(fā)生異常而回滾了,那么A讀到的事務(wù)B的未提交的數(shù)據(jù)就是“過期”的,如果事務(wù)A在這個(gè)“過期”數(shù)據(jù)上進(jìn)行操作,那勢(shì)必會(huì)造成數(shù)據(jù)不一致的情況。因此這種隔離級(jí)別在實(shí)際中很少使用。 讀已提交,指的是一個(gè)事務(wù)開始時(shí),只能看到其他已經(jīng)提交的事務(wù)對(duì)數(shù)據(jù)所做的修改。這種隔離級(jí)別可以防止“臟讀”的問題出現(xiàn)。但是這種情況可能會(huì)出現(xiàn)“不可重復(fù)讀”的問題。所謂不可重復(fù)讀是指,事務(wù)A先后2次讀到的數(shù)據(jù)不一致。舉個(gè)例子,事務(wù)A先讀到小明的賬戶余額為100塊錢,然后再做了其他操作(假設(shè)這些操作沒有改變小明的余額),這個(gè)時(shí)候事務(wù)B將小明的賬戶扣了10塊錢,變成90塊錢了并提交了,由于事務(wù)A可以讀到事務(wù)B提交的修改數(shù)據(jù),所以當(dāng)事務(wù)A執(zhí)行了其他操作后再讀取小明的余額時(shí)就變成90塊了,因此前后2次讀取的數(shù)據(jù)不一致,故出現(xiàn)了“不可重復(fù)讀”的問題。 可重復(fù)讀,指的是可以避免上述“不可重復(fù)讀”的情況出現(xiàn),即它可以保證在同個(gè)事務(wù)中,先后讀到的同一行數(shù)據(jù)是一致的,然而這種隔離級(jí)別下會(huì)出現(xiàn)另一個(gè)問題,就是“幻象讀”?!盎孟笞x”指的是事務(wù)A讀取到了事務(wù)B新增的數(shù)據(jù),因此出現(xiàn)了“幻行”。舉個(gè)例子,事務(wù)A一開始查詢到小明在1月份一共網(wǎng)購了100次,然后再進(jìn)行其他操作(假設(shè)這些操作沒有改變小明的網(wǎng)購記錄數(shù)),然后事務(wù)B插入了一條小明新的網(wǎng)購記錄并提交了,接下來事務(wù)A再統(tǒng)計(jì)出小明的網(wǎng)購記錄,變成101次了,出現(xiàn)了“幻行”,也就是出現(xiàn)了“幻象讀”。 串性化,指的是強(qiáng)制事務(wù)串行執(zhí)行,其可以避免“幻象讀”的問題出現(xiàn),這是最嚴(yán)格的隔離級(jí)別了。因?yàn)榇谢枰诎l(fā)生競(jìng)爭(zhēng)的數(shù)據(jù)上加鎖,所以并發(fā)性能不高,只有在對(duì)數(shù)據(jù)一致性要求非常高且并發(fā)度不高的情況下才會(huì)考慮使用這種隔離級(jí)別。
都看到這里了,不關(guān)注一下么
|