數(shù)據(jù)庫的四大事務(wù)特征
在數(shù)據(jù)庫中,事務(wù)要滿足ACID:
Atomicity 原子性:
- 事務(wù)是一個(gè)原子性質(zhì)的操作單元,事務(wù)里面的對數(shù)據(jù)庫的操作要么都執(zhí)行,要么都不執(zhí)行。
- 例子:銀行轉(zhuǎn)賬時(shí),假設(shè)過程是A賬號扣款,B賬號加款。這兩個(gè)步驟要么都執(zhí)行,要么就都不執(zhí)行。否則如果只執(zhí)行了扣款語句,就提交了,此時(shí)如果突然斷電,A賬號已經(jīng)發(fā)生了扣款,B賬號卻沒收到加款,在生活中就會引起糾紛。
Consistent 一致性:
- 一致性是指在事務(wù)開始之前和事務(wù)結(jié)束以后,數(shù)據(jù)庫的完整性約束沒有被破壞。這是說數(shù)據(jù)庫事務(wù)不能破壞關(guān)系數(shù)據(jù)的完整性以及業(yè)務(wù)邏輯上的一致性。
- 例子: 對銀行轉(zhuǎn)帳事務(wù),不管事務(wù)成功還是失敗,應(yīng)該保證事務(wù)結(jié)束后ACCOUNT表中A和B的存款總額為x元不變。
Isolation 隔離性:
- 數(shù)據(jù)庫允許多個(gè)并發(fā)事務(wù)同事對數(shù)據(jù)進(jìn)行操作,隔離性保證各個(gè)事務(wù)相互獨(dú)立,事務(wù)處理時(shí)的中間狀態(tài)對其它事務(wù)是不可見的,以此防止出現(xiàn)數(shù)據(jù)不一致狀態(tài)。
- 例子: 在Windows中,如果多個(gè)進(jìn)程對同一個(gè)文件進(jìn)行修改是不允許的,Windows通過這種方式來保證不同進(jìn)程的隔離性。
Durable 持久性:
- 一個(gè)事務(wù)處理結(jié)束后,其對數(shù)據(jù)庫的修改就是永久性的,即使系統(tǒng)故障也不會丟失。
臟讀、幻讀和不可重復(fù)讀的概念
臟讀:
所謂臟讀是指一個(gè)事務(wù)中訪問到了另外一個(gè)事務(wù)未提交的數(shù)據(jù),如下圖:
在這里插入圖片描述
如果會話 2 更新 age 為 10,但是在 commit 之前,會話 1 希望得到 age,那么會獲得的值就是更新前的值?;蛘呷绻麜?2 更新了值但是執(zhí)行了 rollback,而會話 1 拿到的仍是 10。這就是臟讀。
不可重復(fù)讀:
一個(gè)事務(wù)查詢同一條記錄2次,得到的結(jié)果不一致:
15352628823137.png
由于在讀取中間變更了數(shù)據(jù),所以會話 1 事務(wù)查詢期間的得到的結(jié)果就不一樣了。
幻讀:
一個(gè)事務(wù)查詢2次,得到的記錄條數(shù)不一致:
15352627898696.png
幻讀是不可重復(fù)讀的一種特殊場景。
MySQL 數(shù)據(jù)隔離級別
MySQL 里有四個(gè)隔離級別:
- Read uncommttied(可以讀取未提交數(shù)據(jù))
- Read committed(可以讀取已提交數(shù)據(jù))
- Repeatable read(可重復(fù)讀)
- Serializable(可串行化)。
不同事務(wù)隔離級別有不同的效果:

[]
在 InnoDB 中,默認(rèn)為 Repeatable 級別,InnoDB 中使用一種被稱為 next-key locking 的策略來避免幻讀(phantom)現(xiàn)象的產(chǎn)生。
隔離級別越高,越能保證數(shù)據(jù)的完整性和一致性,但是對并發(fā)性能的影響也越大。