一、事務(wù)的四大特性(簡(jiǎn)稱ACID)
事務(wù)的使用是數(shù)據(jù)庫(kù)管理系統(tǒng)區(qū)別文件系統(tǒng)的重要特征之一。
事務(wù)擁有四個(gè)重要的特性:原子性(Atomicity)、一致性(Consistency)、隔離性(Isolation)、持久性(Durability)
1、原子性(Atomicity)
事務(wù)是數(shù)據(jù)庫(kù)的邏輯工作單位,事務(wù)開始后所有操作,要么全部做完,要么全部不做,不可能停滯在中間環(huán)節(jié)。事務(wù)執(zhí)行過(guò)程中出錯(cuò),會(huì)回滾到事務(wù)開始前的狀態(tài),所有的操作就像沒(méi)有發(fā)生一樣。例如,如果一個(gè)事務(wù)需要新增 100 條記錄,但是在新增了 10 條記錄之后就失敗了,那么數(shù)據(jù)庫(kù)將回滾對(duì)這 10 條新增的記錄。也就是說(shuō)事務(wù)是一個(gè)不可分割的整體,就像化學(xué)中學(xué)過(guò)的原子,是物質(zhì)構(gòu)成的基本單位。
2、一致性(Consistency)
指事務(wù)將數(shù)據(jù)庫(kù)從一種狀態(tài)轉(zhuǎn)變?yōu)榱硪环N一致的的狀態(tài)。事務(wù)執(zhí)行的結(jié)果必須是使數(shù)據(jù)庫(kù)從一個(gè)一致性狀態(tài)變到另一個(gè)一致性狀態(tài)。一致性與原子性是密切相關(guān)的。事務(wù)開始前和結(jié)束后,數(shù)據(jù)庫(kù)的完整性約束沒(méi)有被破壞。例如工號(hào)帶有唯一屬性,如果經(jīng)過(guò)一個(gè)修改工號(hào)的事務(wù)后,工號(hào)變的非唯一了,則表明一致性遭到了破壞。
3、隔離性(Isolation)
一個(gè)事務(wù)的執(zhí)行不能被其他事務(wù)干擾。要求每個(gè)讀寫事務(wù)的對(duì)象對(duì)其他事務(wù)的操作對(duì)象能互相分離,即該事務(wù)提交前對(duì)其他事務(wù)不可見。 也可以理解為多個(gè)事務(wù)并發(fā)訪問(wèn)時(shí),事務(wù)之間是隔離的,一個(gè)事務(wù)不應(yīng)該影響其它事務(wù)運(yùn)行效果。這指的是在并發(fā)環(huán)境中,當(dāng)不同的事務(wù)同時(shí)操縱相同的數(shù)據(jù)時(shí),每個(gè)事務(wù)都有各自的完整數(shù)據(jù)空間。由并發(fā)事務(wù)所做的修改必須與任何其他并發(fā)事務(wù)所做的修改隔離。例如一個(gè)用戶在更新自己的個(gè)人信息的同時(shí),是不能看到系統(tǒng)管理員也在更新該用戶的個(gè)人信息(此時(shí)更新事務(wù)還未提交)。
注:MySQL 通過(guò)鎖機(jī)制來(lái)保證事務(wù)的隔離性。
這個(gè)會(huì)在后續(xù)講解數(shù)據(jù)庫(kù)隔離級(jí)別
4、持續(xù)性/永久性(Durability)
一個(gè)事務(wù)一旦提交,它對(duì)數(shù)據(jù)庫(kù)中數(shù)據(jù)的改變就應(yīng)該是永久性的。即使發(fā)生宕機(jī)的故障,數(shù)據(jù)庫(kù)也能將數(shù)據(jù)恢復(fù),也就是說(shuō)事務(wù)完成后,事務(wù)對(duì)數(shù)據(jù)庫(kù)的所有更新將被保存到數(shù)據(jù)庫(kù),不能回滾。這只是從事務(wù)本身的角度來(lái)保證,排除 RDBMS(關(guān)系型數(shù)據(jù)庫(kù)管理系統(tǒng),例如 Oracle、MySQL 等)本身發(fā)生的故障。
注:MySQL 使用 redo log 來(lái)保證事務(wù)的持久性。
二、事務(wù)的隔離級(jí)別
多個(gè)事務(wù)并發(fā)訪問(wèn)時(shí),事務(wù)之間是隔離的,一個(gè)事務(wù)不應(yīng)該影響其它事務(wù)運(yùn)行效果。
這指的是在并發(fā)環(huán)境中,當(dāng)不同的事務(wù)同時(shí)操縱相同的數(shù)據(jù)時(shí),每個(gè)事務(wù)都有各自的完整數(shù)據(jù)空間。由并發(fā)事務(wù)所做的修改必須與任何其他并發(fā)事務(wù)所做的修改隔離。事務(wù)查看數(shù)據(jù)更新時(shí),數(shù)據(jù)所處的狀態(tài)要么是另一事務(wù)修改它之前的狀態(tài),要么是另一事務(wù)修改它之后的狀態(tài),事務(wù)不會(huì)查看到中間狀態(tài)的數(shù)據(jù)。
在Windows中,如果多個(gè)進(jìn)程對(duì)同一個(gè)文件進(jìn)行修改是不允許的,Windows通過(guò)這種方式來(lái)保證不同進(jìn)程的隔離性:
企業(yè)開發(fā)中,事務(wù)最復(fù)雜問(wèn)題都是由事務(wù)隔離性引起的。當(dāng)多個(gè)事務(wù)并發(fā)時(shí),SQL Server利用加鎖和阻塞來(lái)保證事務(wù)之間不同等級(jí)的隔離性。一般情況下,完全的隔離性是不現(xiàn)實(shí)的,完全的隔離性要求數(shù)據(jù)庫(kù)同一時(shí)間只執(zhí)行一條事務(wù),這樣會(huì)嚴(yán)重影響性能。想要理解SQL Server中對(duì)于隔離性的保障,首先要了解并發(fā)事務(wù)之間是如何干擾的。
1、事務(wù)之間的相互影響
事務(wù)之間的相互影響分為幾種,分別為:臟讀,不可重復(fù)讀,幻讀,丟失更新
a)、臟讀(Dirty Read)
一個(gè)事務(wù)讀到了另一個(gè)未提交事務(wù)修改過(guò)的數(shù)據(jù)
b)、不可重復(fù)讀(Non-Repeatable Read)
一個(gè)事務(wù)只能讀到另一個(gè)已經(jīng)提交的事務(wù)修改過(guò)的數(shù)據(jù),并且其他事務(wù)每對(duì)該數(shù)據(jù)進(jìn)行一次修改并提交后,該事務(wù)都能查詢得到最新值。(不可重復(fù)讀在讀未提交和讀已提交隔離級(jí)別都可能會(huì)出現(xiàn))
c)、幻讀(Phantom)
一個(gè)事務(wù)先根據(jù)某些條件查詢出一些記錄,之后另一個(gè)事務(wù)又向表中插入了符合這些條件的記錄,原先的事務(wù)再次按照該條件查詢時(shí),能把另一個(gè)事務(wù)插入的記錄也讀出來(lái)。(幻讀在讀未提交、讀已提交、可重復(fù)讀隔離級(jí)別都可能會(huì)出現(xiàn))
例如第一個(gè)事務(wù)對(duì)一個(gè)表中的數(shù)據(jù)進(jìn)行了修改,這種修改涉及到表中的全部數(shù)據(jù)行。同時(shí),第二個(gè)事務(wù)也修改這個(gè)表中的數(shù)據(jù),這種修改是向表中插入一行新數(shù)據(jù)。那么,以后就會(huì)發(fā)生操作第一個(gè)事務(wù)的用戶發(fā)現(xiàn)表中還有沒(méi)有修改的數(shù)據(jù)行,就好象發(fā)生了幻覺一樣.
2、事務(wù)的隔離級(jí)別
MySQL的事務(wù)隔離級(jí)別一共有四個(gè),分別是讀未提交、讀已提交、可重復(fù)讀以及可串行化。 MySQL的隔離級(jí)別的作用就是讓事務(wù)之間互相隔離,互不影響,這樣可以保證事務(wù)的一致性。 隔離級(jí)別比較:可串行化>可重復(fù)讀>讀已提交>讀未提交 隔離級(jí)別對(duì)性能的影響比較:可串行化>可重復(fù)讀>讀已提交>讀未提交 由此看出,隔離級(jí)別越高,所需要消耗的MySQL性能越大(如事務(wù)并發(fā)嚴(yán)重性),為了平衡二者,一般建議設(shè)置的隔離級(jí)別為可重復(fù)讀,MySQL默認(rèn)的隔離級(jí)別也是可重復(fù)讀。
a)、讀未提交(READ UNCOMMITTED)
b)、讀已提交(READ COMMITTED)
c)、可重復(fù)讀(REPEATABLE READ)
d)、可串行化(SERIALIZABLE)
三、spring 事務(wù)傳播機(jī)制
參考文章:
spring 事務(wù)的傳播機(jī)制看這篇就夠了
Spring 事務(wù)傳播機(jī)制
帶你讀懂Spring 事務(wù)——事務(wù)的傳播機(jī)制
四、參考文檔
徹底搞懂 MySQL 事務(wù)的隔離級(jí)別
Innodb中的事務(wù)隔離級(jí)別和鎖的關(guān)系
MySQL 事務(wù)隔離級(jí)別和鎖