數(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默認(rèn)的)
重復(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