面試官:數(shù)據(jù)庫(kù)的隔離是什么意思?
數(shù)據(jù)庫(kù)隔離級(jí)別定義了一個(gè)事務(wù)中的操作與其他并發(fā)事務(wù)之間相互隔離的程度。在多用戶(hù)環(huán)境中,它們?cè)诠芾硎聞?wù)之間的交互、維護(hù)數(shù)據(jù)的完整性和一致性方面至關(guān)重要。
隔離級(jí)別的重要性在于它平衡了數(shù)據(jù)一致性和性能。較高的隔離級(jí)別可以確保更好的數(shù)據(jù)完整性,但可能會(huì)降低性能;而較低的隔離級(jí)別則提高了性能,但可能會(huì)引發(fā)異常。
如果沒(méi)有適當(dāng)?shù)母綦x,可能會(huì)發(fā)生以下問(wèn)題:
- 臟讀:一個(gè)事務(wù)讀取了另一個(gè)未提交事務(wù)寫(xiě)入的數(shù)據(jù),而這些數(shù)據(jù)可能會(huì)被回滾。
- 不可重復(fù)讀:一個(gè)事務(wù)兩次讀取同一行數(shù)據(jù),發(fā)現(xiàn)值不同,因?yàn)榱硪粋€(gè)事務(wù)在兩次讀取之間修改并提交了該行數(shù)據(jù)。
- 幻讀:一個(gè)事務(wù)檢索滿(mǎn)足某個(gè)條件的一組行,但在后續(xù)檢查時(shí)發(fā)現(xiàn)這一組行已經(jīng)發(fā)生變化,因?yàn)榱硪粋€(gè)事務(wù)插入或刪除了行。
下圖說(shuō)明了四種隔離級(jí)別。
- 可序列化(Serializable):最高的隔離級(jí)別,事務(wù)之間完全隔離,仿佛事務(wù)是串行執(zhí)行的而非并發(fā)執(zhí)行的。提供最一致的結(jié)果,但在高并發(fā)下可能導(dǎo)致性能瓶頸。
- 可重復(fù)讀取(Repeatable Read):事務(wù)期間讀取的數(shù)據(jù)與事務(wù)開(kāi)始時(shí)保持一致。一致性較好,性能略有降低。
- 已提交讀?。≧ead Committed):只有在事務(wù)提交后才能讀取修改的數(shù)據(jù)。一致性與性能之間的良好平衡。
- 未提交讀?。≧ead Uncommitted):在事務(wù)提交之前,其他事務(wù)可以讀取修改的數(shù)據(jù)。速度快,但數(shù)據(jù)一致性風(fēng)險(xiǎn)高
隔離由 MVCC(多版本一致性控制)和鎖來(lái)保證
圖中以可重復(fù)讀取為例,演示了 MVCC 的工作原理:
- 每一行有兩個(gè)隱藏列:transaction_id 和 roll_pointer。當(dāng)事務(wù) A 開(kāi)始時(shí),會(huì)創(chuàng)建一個(gè)事務(wù) ID = 201 的新讀視圖。不久后,事務(wù) B 開(kāi)始,又創(chuàng)建了一個(gè)新的讀取視圖,transaction_id=202。
- 現(xiàn)在,事務(wù) A 將余額修改為 200,日志中創(chuàng)建了一條新記錄,roll_pointer 指向舊記錄。在事務(wù) A 提交之前,事務(wù) B 讀取了余額數(shù)據(jù)。事務(wù) B 發(fā)現(xiàn)事務(wù) ID 201 沒(méi)有提交,于是讀取了下一條提交記錄(事務(wù) ID=200)。
- 即使事務(wù) A 提交了,事務(wù) B 仍會(huì)根據(jù)事務(wù) B 啟動(dòng)時(shí)創(chuàng)建的讀取視圖讀取數(shù)據(jù)。因此,事務(wù) B 總是讀取余額=100 的數(shù)據(jù)。
為什么隔離級(jí)別很重要?
- 數(shù)據(jù)一致性:確保事務(wù)結(jié)束后,數(shù)據(jù)庫(kù)處于一致?tīng)顟B(tài)。
- 數(shù)據(jù)完整性:防止出現(xiàn)丟失更新、臟讀或沖突更改等問(wèn)題。
- 并發(fā)控制:在訪(fǎng)問(wèn)數(shù)據(jù)的用戶(hù)或操作數(shù)量與數(shù)據(jù)庫(kù)一致性之間找到平衡。
- 性能優(yōu)化:幫助在性能和嚴(yán)格的事務(wù)規(guī)則之間進(jìn)行權(quán)衡和優(yōu)化。
在生產(chǎn)環(huán)境中,我們要避免錯(cuò)誤地設(shè)置隔離級(jí)別,這會(huì)造成不可預(yù)計(jì)的后果。