1坤候、ACID
ACID照卦,是指在可靠數(shù)據(jù)庫(kù)管理系統(tǒng)(DBMS)中爬范,事務(wù)(transaction)所應(yīng)該具有的四個(gè)特性:原子性(Atomicity)痪宰、一致性(Consistency)行疏、隔離性(Isolation)匆光、持久性(Durability).這是可靠數(shù)據(jù)庫(kù)所應(yīng)具備的幾個(gè)特性。
2酿联、事務(wù)
事務(wù)(Transaction)是并發(fā)控制的基本單位终息。所謂的事務(wù)夺巩,它是一個(gè)操作序列,這些操作要么都執(zhí)行周崭,要么都不執(zhí)行柳譬,它是一個(gè)不可分割的工作單位。例如续镇,銀行轉(zhuǎn)賬工作:從一個(gè)賬號(hào)扣款并使另一個(gè)賬號(hào)增款美澳,這兩個(gè)操作要么都執(zhí)行,要么都不執(zhí)行摸航。所以制跟,應(yīng)該把它們看成一個(gè)事務(wù)。事務(wù)是數(shù)據(jù)庫(kù)維護(hù)數(shù)據(jù)一致性的單位酱虎,在每個(gè)事務(wù)結(jié)束時(shí)雨膨,都能保持?jǐn)?shù)據(jù)一致性。
3逢净、事務(wù)的語(yǔ)句
開(kāi)始事物:BEGIN TRANSACTION
提交事物:COMMIT TRANSACTION
回滾事務(wù):ROLLBACK TRANSACTION
4哥放、數(shù)據(jù)庫(kù)所具有的四個(gè)事務(wù)特性
(1)原子性(Atomic)
即要么都發(fā)生歼指,要么都不發(fā)生爹土。事務(wù)是一個(gè)不可再分割的工作單位。
例子:銀行的轉(zhuǎn)賬
A轉(zhuǎn)給B 100塊錢(qián)踩身,在轉(zhuǎn)賬的過(guò)程中胀茵,如果A扣款成功,那么B 的賬戶必然多出了一百塊錢(qián)挟阻,如果A轉(zhuǎn)賬過(guò)程出現(xiàn)的異常琼娘,那么事務(wù)回滾,A的賬戶不會(huì)扣款附鸽,B的賬戶也不會(huì)多出 100塊錢(qián)脱拼。
在A扣款和B的賬戶中多出錢(qián),這兩個(gè)步驟要么都執(zhí)行坷备,要么都不執(zhí)行熄浓,如果只執(zhí)行了其中的一個(gè),那么就會(huì)出現(xiàn)錢(qián)財(cái)?shù)募m紛省撑。
解決方法
在數(shù)據(jù)庫(kù)管理系統(tǒng)(DBMS)中赌蔑,默認(rèn)情況下一條SQL就是一個(gè)單獨(dú)事務(wù),事務(wù)是自動(dòng)提交的竟秫。只有顯式的使用start transaction開(kāi)啟一個(gè)事務(wù)娃惯,才能將一個(gè)代碼塊放在事務(wù)中執(zhí)行。保障事務(wù)的原子性是數(shù)據(jù)庫(kù)管理系統(tǒng)的責(zé)任肥败,為此許多數(shù)據(jù)源采用日志機(jī)制趾浅。例如愕提,SQL Server使用一個(gè)預(yù)寫(xiě)事務(wù)日志,在將數(shù)據(jù)提交到實(shí)際數(shù)據(jù)頁(yè)面前皿哨,先寫(xiě)在事務(wù)日志上揪荣。(MySQL的Innodb日志機(jī)制以后在寫(xiě))。
(2)一致性(Consistency)
一致性是指在事務(wù)開(kāi)始之前和事務(wù)結(jié)束以后往史,數(shù)據(jù)庫(kù)的完整性約束沒(méi)有被破壞仗颈。這是說(shuō)數(shù)據(jù)庫(kù)事務(wù)不能破壞關(guān)系數(shù)據(jù)的完整性以及業(yè)務(wù)邏輯上的一致性。
也就是說(shuō)不管局部之間是怎么發(fā)生變化的椎例,但是在總體上不能發(fā)生變化挨决,數(shù)據(jù)庫(kù)的完整性不能被破壞。
例子:
仍然用銀行的轉(zhuǎn)賬來(lái)說(shuō)订歪,如果A有100塊錢(qián)脖祈,B有100塊錢(qián),那么不論A與B之間經(jīng)過(guò)多少次的轉(zhuǎn)賬刷晋,但是A+B的賬戶總額度還是應(yīng)該為200塊錢(qián)盖高,這個(gè)是不能有變化的。要維持這個(gè)總體的一致性眼虱。
解決方法
保障事務(wù)的一致性喻奥,可以從以下兩個(gè)層面入手
2.1數(shù)據(jù)庫(kù)機(jī)制層面
數(shù)據(jù)庫(kù)層面的一致性是,在一個(gè)事務(wù)執(zhí)行之前和之后捏悬,數(shù)據(jù)會(huì)符合你設(shè)置的約束(唯一約束撞蚕,外鍵約束,Check約束等)和觸發(fā)器設(shè)置。這一點(diǎn)是由SQL SERVER進(jìn)行保證的过牙。比如轉(zhuǎn)賬甥厦,則可以使用CHECK約束兩個(gè)賬戶之和等于200來(lái)達(dá)到一致性目的
2.2業(yè)務(wù)層面
對(duì)于業(yè)務(wù)層面來(lái)說(shuō),一致性是保持業(yè)務(wù)的一致性寇钉。這個(gè)業(yè)務(wù)一致性需要由開(kāi)發(fā)人員進(jìn)行保證刀疙。當(dāng)然,很多業(yè)務(wù)方面的一致性扫倡,也可以通過(guò)轉(zhuǎn)移到數(shù)據(jù)庫(kù)機(jī)制層面進(jìn)行保證谦秧。
(3)隔離性(Isolation)
在并發(fā)的環(huán)境中,多個(gè)事務(wù)之間是相互隔離的镊辕,一個(gè)事務(wù)的運(yùn)行運(yùn)行不應(yīng)該影響其他的事務(wù)的運(yùn)行效果油够。
在并發(fā)的環(huán)境中,當(dāng)不同的事務(wù)同是操作數(shù)據(jù)的時(shí)候征懈,他們都應(yīng)該有自己完整的數(shù)據(jù)操作環(huán)境石咬,由其他并發(fā)事務(wù)所做的修改必須與其他事務(wù)所做的修改隔離開(kāi)。事務(wù)去查看卖哎、修改或者其他操作去操作數(shù)據(jù)的時(shí)候鬼悠,這組數(shù)據(jù)要么處在其他事務(wù)修改(或其他操作)它之前的狀態(tài)删性,要么是之后的狀態(tài),不能處在其他事務(wù)未提交的狀態(tài)焕窝,中間的狀態(tài)蹬挺。
解決方法:
當(dāng)事務(wù)并發(fā)是,sql server會(huì)采用加鎖或阻塞來(lái)保證事務(wù)之間不同等級(jí)的隔離性它掂。但是巴帮,如果,要實(shí)現(xiàn)完全隔離是不現(xiàn)實(shí)的虐秋,因?yàn)槿绻獙?shí)現(xiàn)完全隔離榕茧,那么要求數(shù)據(jù)庫(kù)在同一時(shí)間,只運(yùn)行同一個(gè)事務(wù)客给,這會(huì)很浪費(fèi)用押、影響數(shù)據(jù)庫(kù)的性能,因此靶剑,只能盡可能的實(shí)現(xiàn)隔離蜻拨。
事務(wù)之間的干擾:
3.1事務(wù)之間的干擾,主要是以下幾種
臟讀桩引、幻讀缎讼、不可重復(fù)讀、丟失更新阐污。
3.2臟讀
臟讀就是指當(dāng)一個(gè)事務(wù)正在訪問(wèn)數(shù)據(jù)休涤,并且對(duì)數(shù)據(jù)進(jìn)行了修改咱圆,而這種修改還沒(méi)有提交到數(shù)據(jù)庫(kù)中笛辟,這時(shí),另外一個(gè)事務(wù)也訪問(wèn)這個(gè)數(shù)據(jù)序苏,然后使用了這個(gè)數(shù)據(jù)手幢。因?yàn)檫@個(gè)數(shù)據(jù)是還沒(méi)有提交的數(shù)據(jù),那么另外一個(gè)事務(wù)讀到的這個(gè)數(shù)據(jù)是臟數(shù)據(jù)忱详,依據(jù)臟數(shù)據(jù)所做的操作可能是不正確的围来。
如下圖
如圖,發(fā)生了臟讀匈睁,那么B肯定會(huì)因?yàn)榇瞬僮鞫斐蓳p失监透。
3.3幻讀
幻讀是指當(dāng)事務(wù)不是獨(dú)立執(zhí)行時(shí)發(fā)生的一種現(xiàn)象。
事務(wù)A讀取與搜索條件相匹配的若干行航唆。事務(wù)B以插入或刪除行等方式來(lái)修改事務(wù)A的結(jié)果集胀蛮,然后再提交。
比如這種修改涉及到表中的“全部數(shù)據(jù)行”糯钙。同時(shí)粪狼,第二個(gè)事務(wù)也修改這個(gè)表中的數(shù)據(jù)退腥,這種修改是向表中插入“一行新數(shù)據(jù)”。那么再榄,以后就會(huì)發(fā)生操作第一個(gè)事務(wù)的用戶發(fā)現(xiàn)表中還存在沒(méi)有修改的數(shù)據(jù)行狡刘,就好象發(fā)生了幻覺(jué)一樣.一般解決幻讀的方法是增加范圍鎖RangeS,鎖定檢索范圍為只讀困鸥,這樣就避免了幻讀嗅蔬。
如圖:
在事務(wù)A處理了以后,事務(wù)B又進(jìn)行了操作疾就,那么购城,結(jié)果就是,出現(xiàn)了好像是幻覺(jué)一樣的感覺(jué)虐译,事務(wù)A并沒(méi)有進(jìn)行處理瘪板。
3.4不可重復(fù)讀
不可重復(fù)讀,是指在數(shù)據(jù)庫(kù)訪問(wèn)中漆诽,一個(gè)事務(wù)范圍內(nèi)兩個(gè)相同的查詢(xún)卻返回了不同數(shù)據(jù)侮攀。
這是由于查詢(xún)時(shí)系統(tǒng)中其他事務(wù)修改的提交而引起的。比如事務(wù)T1讀取某一數(shù)據(jù)厢拭,事務(wù)T2讀取并修改了該數(shù)據(jù)兰英,T1為了對(duì)讀取值進(jìn)行檢驗(yàn)而再次讀取該數(shù)據(jù),便得到了不同的結(jié)果供鸠。
一種更易理解的說(shuō)法是:在一個(gè)事務(wù)內(nèi)畦贸,多次讀同一個(gè)數(shù)據(jù)。在這個(gè)事務(wù)還沒(méi)有結(jié)束時(shí)楞捂,另一個(gè)事務(wù)也訪問(wèn)該同一數(shù)據(jù)薄坏。那么,在第一個(gè)事務(wù)的兩次讀數(shù)據(jù)之間寨闹。由于第二個(gè)事務(wù)的修改胶坠,那么第一個(gè)事務(wù)讀到的數(shù)據(jù)可能不一樣,這樣就發(fā)生了在一個(gè)事務(wù)內(nèi)兩次讀到的數(shù)據(jù)是不一樣的繁堡,因此稱(chēng)為不可重復(fù)讀沈善,即原始讀取不可重復(fù)。
如圖:
如圖椭蹄,這么查詢(xún)闻牡,會(huì)使兩次查詢(xún)的結(jié)果發(fā)生不同。
3.5更新丟失
兩個(gè)事務(wù)同時(shí)讀取同一條記錄绳矩,A先修改記錄罩润,B也修改記錄(B是不知道A修改過(guò)),B提交數(shù)據(jù)后B的修改結(jié)果覆蓋了A的修改結(jié)果埋酬。
3.6四種隔離級(jí)別
Read uncommitted(未授權(quán)讀取哨啃、讀未提交):
如果一個(gè)事務(wù)已經(jīng)開(kāi)始寫(xiě)數(shù)據(jù)烧栋,則另外一個(gè)事務(wù)則不允許同時(shí)進(jìn)行寫(xiě)操作,但允許其他事務(wù)讀此行數(shù)據(jù)拳球。該隔離級(jí)別可以通過(guò)“排他寫(xiě)鎖”實(shí)現(xiàn)审姓。
避免了更新丟失,卻可能出現(xiàn)臟讀祝峻。也就是說(shuō)事務(wù)B讀取到了事務(wù)A未提交的數(shù)據(jù)魔吐。
Read committed(授權(quán)讀取、讀提交):
讀取數(shù)據(jù)的事務(wù)允許其他事務(wù)繼續(xù)訪問(wèn)該行數(shù)據(jù)莱找,但是未提交的寫(xiě)事務(wù)將會(huì)禁止其他事務(wù)訪問(wèn)該行酬姆。
該隔離級(jí)別避免了臟讀,但是卻可能出現(xiàn)不可重復(fù)讀奥溺。事務(wù)A事先讀取了數(shù)據(jù)辞色,事務(wù)B緊接了更新了數(shù)據(jù),并提交了事務(wù)浮定,而事務(wù)A再次讀取該數(shù)據(jù)時(shí)相满,數(shù)據(jù)已經(jīng)發(fā)生了改變。
Repeatable read(可重復(fù)讀辱胱洹):
讀取數(shù)據(jù)的事務(wù)將會(huì)禁止寫(xiě)事務(wù)(但允許讀事務(wù))立美,寫(xiě)事務(wù)則禁止任何其他事務(wù)。
避免了不可重復(fù)讀取和臟讀方灾,但是有時(shí)可能出現(xiàn)幻讀建蹄。這可以通過(guò)“共享讀鎖”和“排他寫(xiě)鎖”實(shí)現(xiàn)。
Serializable(序列化):
提供嚴(yán)格的事務(wù)隔離裕偿。它要求事務(wù)序列化執(zhí)行洞慎,事務(wù)只能一個(gè)接著一個(gè)地執(zhí)行,但不能并發(fā)執(zhí)行击费。如果僅僅通過(guò)“行級(jí)鎖”是無(wú)法實(shí)現(xiàn)事務(wù)序列化的拢蛋,必須通過(guò)其他機(jī)制保證新插入的數(shù)據(jù)不會(huì)被剛執(zhí)行查詢(xún)操作的事務(wù)訪問(wèn)到。
序列化是最高的事務(wù)隔離級(jí)別蔫巩,同時(shí)代價(jià)也花費(fèi)最高,性能很低快压,一般很少使用圆仔,在該級(jí)別下,事務(wù)順序執(zhí)行蔫劣,不僅可以避免臟讀坪郭、不可重復(fù)讀,還避免了幻讀脉幢。
隔離級(jí)別越高歪沃,越能保證數(shù)據(jù)的完整性和一致性嗦锐,但是對(duì)并發(fā)性能的影響也越大。對(duì)于多數(shù)應(yīng)用程序沪曙,可以?xún)?yōu)先考慮把數(shù)據(jù)庫(kù)系統(tǒng)的隔離級(jí)別設(shè)為Read Committed奕污。它能夠避免臟讀取,而且具有較好的并發(fā)性能液走。盡管它會(huì)導(dǎo)致不可重復(fù)讀碳默、幻讀和第二類(lèi)丟失更新這些并發(fā)問(wèn)題,在可能出現(xiàn)這類(lèi)問(wèn)題的個(gè)別場(chǎng)合缘眶,可以由應(yīng)用程序采用悲觀鎖或樂(lè)觀鎖來(lái)控制嘱根。
大多數(shù)數(shù)據(jù)庫(kù)的默認(rèn)級(jí)別就是Read committed,比如Sql Server , Oracle巷懈。
Mysql的默認(rèn)隔離級(jí)別就是Repeatable read该抒。
隔離級(jí)別 ? ? ? ? ? ? ? ? ? 臟讀 ? ? 不可重復(fù)讀 ? ?幻讀 ? ? ? 更新丟失 ? ? 并發(fā)模型
Read uncommitted ? ? 是 ? ? ? ? ? ? 是 ? ? ? ? ? ? ?是 ? ? ? ? ? ? ?否 ? ? ? ? ? ?悲觀鎖
Read committed ? ? ? ? 否 ? ? ? ? ? ? 是 ? ? ? ? ? ? 是 ? ? ? ? ? ? ?是 ? ? ? ? ? ? 悲觀鎖
Repeatable read ? ? ? ? 否 ? ? ? ? ? ?否 ? ? ? ? ? ? ?是 ? ? ? ? ? ? 是 ? ? ? ? ? 悲觀鎖
Serializable ? ? ? ? ? ? ? ? 否 ? ? ? ? ? ? 否 ? ? ? ? ? ? ?否 ? ? ? ? ? ? 否 ? ? ? ? ? ?悲觀鎖
(4)一致性
持久性,意味著在事務(wù)完成以后顶燕,該事務(wù)所對(duì)數(shù)據(jù)庫(kù)所作的更改便持久的保存在數(shù)據(jù)庫(kù)之中柔逼,并不會(huì)被回滾。(此時(shí)即使系統(tǒng)崩潰割岛,修改的數(shù)據(jù)也不會(huì)丟失愉适。持久性是個(gè)有占模糊的概念,因?yàn)閷?shí)際上持久性也分很多不同的級(jí)別癣漆。有些持久性策略能夠提供非常強(qiáng)的安全保障维咸,而有些則未必,而且不可能有能做到100%的持久性保證的策略惠爽。)