何為數(shù)據(jù)庫ACID?

什么是數(shù)據(jù)庫ACID?

  事務(wù)在當(dāng)今的企業(yè)系統(tǒng)無處不在,即使在高并發(fā)環(huán)境下也可以提供數(shù)據(jù)的完整性。一個(gè)事務(wù)是一個(gè)只包含所有讀/寫操作成功的集合。如下圖:


一個(gè)事務(wù)本質(zhì)上有四個(gè)特點(diǎn)ACID:

Atomicity原子性

Consistency一致性

Isolation隔離性

Durability耐久性

原子性

原子性任務(wù)是一個(gè)獨(dú)立的操作單元,是一種要么全部是,要么全部不是的原子單位性的操作。

一致性

一個(gè)事務(wù)可以封裝狀態(tài)改變(除非它是一個(gè)只讀的)。事務(wù)必須始終保持系統(tǒng)處于一致的狀態(tài),不管在任何給定的時(shí)間并發(fā)事務(wù)有多少。

一致性有下面特點(diǎn):

如果一個(gè)操作觸發(fā)輔助操作(級(jí)聯(lián),觸發(fā)器),這些也必須成功,否則交易失敗。

如果系統(tǒng)是由多個(gè)節(jié)點(diǎn)組成,一致性規(guī)定所有的變化必須傳播到所有節(jié)點(diǎn)(多主復(fù)制)。如果從站節(jié)點(diǎn)是異步更新,那么我們打破一致性規(guī)則,系統(tǒng)成為“最終一致性”。

一個(gè)事務(wù)是數(shù)據(jù)狀態(tài)的切換,因此,如果事務(wù)是并發(fā)多個(gè),系統(tǒng)也必須如同串行事務(wù)一樣操作。

在現(xiàn)實(shí)中,事務(wù)系統(tǒng)遭遇并發(fā)請(qǐng)求時(shí),這種串行化是有成本的, Amdahl法則描述如下:它是描述序列串行執(zhí)行和并發(fā)之間的關(guān)系。

“一個(gè)程序在并行計(jì)算情況下使用多個(gè)處理器所能提升的速度是由這個(gè)程序中串行執(zhí)行部分的時(shí)間決定的?!?/p>

大多數(shù)數(shù)據(jù)庫管理系統(tǒng)選擇(默認(rèn)情況下)是放寬一致性,以達(dá)到更好的并發(fā)性。

隔離性

事務(wù)是并發(fā)控制機(jī)制,他們交錯(cuò)使用時(shí)也能提供一致性。隔離讓我們隱藏來自外部世界未提交的狀態(tài)變化,一個(gè)失敗的事務(wù)不應(yīng)該破壞系統(tǒng)的狀態(tài)。隔離是通過用悲觀或樂觀鎖機(jī)制實(shí)現(xiàn)的。


耐久性

一個(gè)成功的事務(wù)將永久性地改變系統(tǒng)的狀態(tài),所以在它結(jié)束之前,所有導(dǎo)致狀態(tài)的變化都記錄在一個(gè)持久的事務(wù)日志中。如果我們的系統(tǒng)突然受到系統(tǒng)崩潰或斷電,那么所有未完成已提交的事務(wù)可能會(huì)重演。


盡管一些數(shù)據(jù)庫系統(tǒng)提供多版本并發(fā)控制MVCC, 他們的并發(fā)控制都是通過鎖完成,因此,鎖會(huì)增加執(zhí)行的串行性,影響并發(fā)性。


SQL標(biāo)準(zhǔn)規(guī)定了四個(gè)隔離水平:

READ_UNCOMMITTED

READ_COMMITTED

REPETABLE_READ

SERIALIZABLE

隔離級(jí)別????????????????????????????????????臟讀????????????????非重復(fù)讀????????????????Phantom read

READ_UNCOMMITTED????????????allowed????????????allowed????????????????????allowed

READ_COMMITTED? ? ? ? ? ? ? ? ? prevented????????allowed????????????????????allowed

REPETABLE_READ????????????????????prevented????????prevented????????????????allowed

SERIALIZABLE????????????????????????????prevented? ? ? ? prevented????????????????prevented


臟讀

臟讀發(fā)生在:當(dāng)一個(gè)事務(wù)允許讀取一個(gè)被其他事務(wù)改變但是未提交的狀態(tài)時(shí),這是因?yàn)椴]有鎖阻止讀取,如上圖,你看到第二個(gè)事務(wù)讀取了一個(gè)并不一致的值,不一致的意思是,這個(gè)值是無效的,因?yàn)樾薷倪@個(gè)值的第一個(gè)事務(wù)已經(jīng)回滾,也就是說,第一個(gè)事務(wù)修改了這個(gè)值,但是未提交確認(rèn),卻被第二個(gè)事務(wù)讀取,第一個(gè)事務(wù)又放棄修改,悔棋了,而第二個(gè)事務(wù)就得到一個(gè)臟數(shù)據(jù)。

非重復(fù)讀

反復(fù)讀同一個(gè)數(shù)據(jù)卻得到不同的結(jié)果,這是因?yàn)樵诜磸?fù)幾次讀取的過程中,數(shù)據(jù)被修改了,這就導(dǎo)致我們使用了stale數(shù)據(jù),這可以通過一個(gè)共享讀鎖來避免。這是隔離級(jí)別READ_COMMITTED會(huì)導(dǎo)致可重復(fù)讀的原因。設(shè)置共享讀鎖也就是隔離級(jí)別提高到REPETABLE_READ。

Phantom 讀

當(dāng)?shù)诙€(gè)事務(wù)插入一行記錄,而正好之前第一個(gè)事務(wù)查詢了應(yīng)該包含這個(gè)新紀(jì)錄的數(shù)據(jù),那么這個(gè)查詢事務(wù)的結(jié)果里肯定沒有包含這個(gè)剛剛新插入的數(shù)據(jù),這時(shí)幻影讀發(fā)生了,通過變化鎖和predicate locking避免。

下圖是主流數(shù)據(jù)庫的默認(rèn)隔離級(jí)別:

Database????????????????????????????????Default isolation Level

Oracle? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? READ_COMMITTED

MySQL? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?REPETABLE_READ

Microsoft SQL Server? ? ? ? ?READ_COMMITTED

PostgreSQL????????????????????????READ_COMMITTED

DB2????????????????????????????????????CURSOR STABILITY (a.k.a READ_COMMITTED)

READ_COMMITED 是正確的選擇,因?yàn)镾ERIALIZABLE雖然能在不同事務(wù)發(fā)生時(shí)避免stale數(shù)據(jù),也就是避免上述丟失剛剛修改的數(shù)據(jù),但是性能是最低的,因?yàn)槭且环N最大化的串行。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容