數(shù)據(jù)庫事務(wù)的四大特點
上學(xué)的時候我們都學(xué)過事務(wù)的四大特點ACID,很多時候我們都不知道ACID到底是個什么東西赞赖?今天我們就來好好分析分析是什么叫做ACID嬉挡。
- A(Automicity)
就是我們經(jīng)常所說的原子性,所謂的原子性喷户,就是一組操作要么不做要么全做,不能有做了一半的情況访锻。 - C (Consistency)
一致性褪尝,是指事務(wù)必須使數(shù)據(jù)庫從一個一致性狀態(tài)切換到另外一個一致性狀態(tài)闹获,也就是事務(wù)在執(zhí)行前和執(zhí)行之后狀態(tài)必須一致。
看到一個很好的說明一致性的例子河哑,銀行兩個賬戶總共1萬塊錢避诽,不論他們之間發(fā)生多少次轉(zhuǎn)賬,總共的金額應(yīng)該是1萬塊不變璃谨。
- I (Isolayion)
隔離性沙庐,就是多個并發(fā)事務(wù)會被隔離開,相互之間不會互相干擾佳吞。
例如多個用戶在操作數(shù)據(jù)庫同一張表的時候拱雏,會產(chǎn)生多個事務(wù),這些事務(wù)執(zhí)行是串行化的底扳。
- D (Durability)
永久性铸抑,也就是這個事務(wù)被提交了,就不會再被更改了衷模。
如果沒有事務(wù)的隔離性鹊汛,會發(fā)生什么呢?
- 臟讀
有兩個事務(wù)阱冶,A和B,如果同時操作數(shù)據(jù)庫的同一張表刁憋,在沒有隔離性的前提下,A的操作尚未提交木蹬,B同時操作的話至耻,B會讀到A尚未提交的數(shù)據(jù),這就造成了臟讀届囚。
update account set money=money+100 where name=’B’; (此時A通知B)
update account set money=money - 100 where name=’A’;
如果執(zhí)行完一個update有梆,此時b去查詢的時候發(fā)現(xiàn)賬戶確實多了100,而后一個update執(zhí)行失敗意系,事務(wù)回滾泥耀,此時b的賬戶并沒有多100塊,就會造成臟讀蛔添。
- 不可重復(fù)讀
不可重復(fù)讀是指痰催,在一個事務(wù)里多次查詢得到的結(jié)果不一致,原因是因為在這個事務(wù)執(zhí)行的同時其他事務(wù)操作了數(shù)據(jù)并且已經(jīng)提交迎瞧。
// 第一個事務(wù)第一查詢
select * from t_user t where t.name like '%a%'夸溶;
// 第二個事務(wù)執(zhí)行了update,并且已經(jīng)提交
update t_user set name value =' amily'凶硅;
// 第一個事務(wù)再次查詢
select * from t_user t where t.name like '%a%'缝裁;
這樣兩次查詢的結(jié)果就是不一致的。
臟讀和不可重復(fù)讀的區(qū)別是什么呢足绅?
臟讀是一個事務(wù)讀到另一個事務(wù)未提交的數(shù)據(jù)捷绑,不可重復(fù)讀是指一個事務(wù)讀到另一個已經(jīng)提交了的事務(wù)韩脑。
- 幻讀
幻讀是事務(wù)非獨立執(zhí)行的一種現(xiàn)象。例如事務(wù)a把數(shù)據(jù)庫里面某張表的數(shù)據(jù)從1修改為2粹污,這時事務(wù)b往數(shù)據(jù)庫里面有插入了一條為1的數(shù)據(jù)段多,這時事務(wù)a再做查詢的時候會發(fā)現(xiàn)有多出了一個為1的記錄,就會感覺很奇怪壮吩,以為自己產(chǎn)生幻覺了进苍,所以就叫做幻讀了,其實這個時候讀到的數(shù)據(jù)是事務(wù)b插入到數(shù)據(jù)庫的鸭叙。
// 第一個事務(wù)更新
update t_user set name=2 where name=1;
// 第二個事務(wù)insert
insert into t_user (name) value (1)觉啊;
// 第一個事務(wù)查詢
select * from t_user t where t.name = 1;
數(shù)據(jù)庫事務(wù)的四大隔離級別
- read-uncommitted
讀未提交,如果是讀未提交肯定會出現(xiàn)臟讀递雀,幻讀柄延,不可重復(fù)讀 - read-committed
讀已提交,如果讀已經(jīng)提交的話缀程,肯定不會出現(xiàn)臟讀了搜吧,但是幻讀,不可重復(fù)讀肯定還是會出現(xiàn)的 - repeatable-read (mysql innodb默認的)
重復(fù)讀杨凑,可以避免臟讀和不可重復(fù)讀滤奈,通過間隙鎖可以避免幻讀。 - serializable
串行化撩满,這個就牛逼了蜒程,意思就是一個一個的來,當(dāng)然什么不可重復(fù)讀伺帘,幻讀昭躺,臟讀統(tǒng)統(tǒng)的搞定。
總結(jié)一下:
隔離級別 | Dirty reads | non-repeatable reads | phantom reads |
---|---|---|---|
Serializable | 不會 | 不會 | 不會 |
READ COMMITTED | 不會 | 會 | 會 |
REPEATABLE READ | 不會 | 不會 | 會 |
Read Uncommitted | 會 | 會 | 會 |
性能來說的話是:
read-uncommitted>read-committed>reaptable-read>serializable
從隔離性來說:
read-uncommitted<read-committed<reaptable-read<serializable