事務(wù)是指一組數(shù)據(jù)庫操作,要么全部執(zhí)行成功,要么全部不執(zhí)行,以保證數(shù)據(jù)的一致性和完整性。事務(wù)通常包括一組SQL語句,這些語句共同完成某個業(yè)務(wù)流程,如銀行轉(zhuǎn)賬。
事務(wù)的四大特性(ACID)
- 原子性(atomicity):?事務(wù)的最小工作單元,要么全成功,要么全失敗。
- 一致性(consistency):?事務(wù)開始和結(jié)束后,數(shù)據(jù)庫的完整性不會被破壞。
- 隔離性(isolation):?不同事務(wù)之間互不影響,四種隔離級別為RU(讀未提交)、RC(讀已提交)、RR(可重復(fù)讀)、SERIALIZABLE (串行化)。
- 持久性(durability):?事務(wù)提交后,對數(shù)據(jù)的修改是永久性的,即使系統(tǒng)故障也不會丟失。
臟讀 | 臟讀 | 不可重復(fù)讀 | 幻讀 |
Read uncommitted | ?? | ?? | ?? |
Read committed | × | ?? | ?? |
Repeatable read | × | × | ?? |
Serializable | × | × | × |
讀未提交(Read UnCommitted/RU)
- 有臟讀問題,一個事務(wù)可以讀取到另一個事務(wù)未提交的數(shù)據(jù)。這種隔離級別是最不安全的一種。也就是說,一個事務(wù)正在對一條記錄做修改,在這個事務(wù)完成并提交之前,這條數(shù)據(jù)是處于待定狀態(tài)的(可能提交也可能回滾),這時,第二個事務(wù)來讀取這條沒有提交的數(shù)據(jù),并做進(jìn)一步的處理,就會產(chǎn)生未提交的數(shù)據(jù)依賴關(guān)系,這種現(xiàn)象被稱為臟讀。
臟讀 | |
事務(wù)1 | 事務(wù)2 |
START TRANSACTION | START TRANSACTION |
select age from user where id=1;
<res=20> | |
update user set age=30 where id=1; | |
select age from user where id=1;
<res=30> | |
commit; | commit; |
讀已提交(Read Committed/RC)
- 有不可重復(fù)讀問題,一個事務(wù)先后讀取同一條記錄,而事務(wù)在兩次讀取之間該數(shù)據(jù)被其它事務(wù)所修改,則兩次讀取的數(shù)據(jù)不同,我們稱之為不可重復(fù)讀。
不可重復(fù)讀 | |
事務(wù)1 | 事務(wù)2 |
START TRANSACTION | START TRANSACTION |
select age from user where id=1;
<res=20> | |
update user set age=30 where id=1; | |
commit; | |
select age from user where id=1;
<res=30> | |
commit; |
可重復(fù)讀(Repeatable Read/RR)
- 有幻讀問題,一個事物讀可以讀取到其他事務(wù)提交的數(shù)據(jù),但是在RR隔離級別下,當(dāng)前讀取此條數(shù)據(jù)只可讀取一次,在當(dāng)前事務(wù)中,不論讀取多少次,數(shù)據(jù)仍然是第一次讀取的值,不會因?yàn)樵诘谝淮巫x取之后,其他事務(wù)再修改提交此數(shù)據(jù)而產(chǎn)生改變。因此也成為幻讀,因?yàn)樽x出來的數(shù)據(jù)并不一定就是最新的數(shù)據(jù)。
- 重復(fù)讀可以解決不可重復(fù)讀問題。寫到這里,應(yīng)該明白的一點(diǎn)就是,不可重復(fù)讀對應(yīng)的是修改,即UPDATE操作。但是可能還會有幻讀問題。因?yàn)榛米x問題對應(yīng)的是插入INSERT操作,而不是UPDATE操作。
幻讀 | |
事務(wù)1 | 事務(wù)2 |
START TRANSACTION | START TRANSACTION |
select count(*) from user where age=30;
<res=1> | |
insert into user(age) values(30); | |
commit; | |
select count(*) from user where age=30;
<res=2> | |
commit; |
串行化(Serializable)
- 所有的數(shù)據(jù)庫的讀或者寫操作都為串行執(zhí)行,當(dāng)前隔離級別下只支持單個請求同時執(zhí)行,所有的操作都需要隊(duì)列執(zhí)行。所以種隔離級別下所有的數(shù)據(jù)是最穩(wěn)定的,但是性能也是最差的。數(shù)據(jù)庫的鎖實(shí)現(xiàn)就是這種隔離級別的更小粒度版本。
- Serializable 是最高的事務(wù)隔離級別,在該級別下,事務(wù)串行化順序執(zhí)行,可以避免臟讀、不可重復(fù)讀與幻讀。但是這種事務(wù)隔離級別效率低下,比較耗數(shù)據(jù)庫性能,一般不使用。
選擇合適的隔離級別需要考慮以下幾個因素:
- 并發(fā)性要求:如果系統(tǒng)并發(fā)量較低,選擇較低的隔離級別可以提高性能,而對于高并發(fā)系統(tǒng),需要選擇較高的隔離級別來確保數(shù)據(jù)的正確性。
- 數(shù)據(jù)一致性要求:如果數(shù)據(jù)的一致性要求比較高,需要選擇較高的隔離級別,否則可能會出現(xiàn)臟讀、不可重復(fù)讀等問題。
- 事務(wù)的長度和復(fù)雜度:如果事務(wù)的長度和復(fù)雜度較高,需要選擇較高的隔離級別來確保數(shù)據(jù)的正確性。
- 數(shù)據(jù)庫的性能和資源使用:較高的隔離級別可能會對數(shù)據(jù)庫性能和資源使用產(chǎn)生較大影響,需要權(quán)衡考慮。
選擇合適的隔離級別需要根據(jù)具體業(yè)務(wù)場景和系統(tǒng)需求來進(jìn)行評估和選擇。一般來講,在企業(yè)中主要用RC和RR隔離級別,高并發(fā)場景,事務(wù)比較簡單,一般使用RC。一致性要求比較高的情況一般使用RR。
版權(quán)聲明:本文內(nèi)容由互聯(lián)網(wǎng)用戶自發(fā)貢獻(xiàn),該文觀點(diǎn)僅代表作者本人。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如發(fā)現(xiàn)本站有涉嫌抄襲侵權(quán)/違法違規(guī)的內(nèi)容, 請發(fā)送郵件至2705686032@qq.com 舉報(bào),一經(jīng)查實(shí),本站將立刻刪除。原文轉(zhuǎn)載: 原文出處: