一、事務(wù)屬性
? ? 原子性(Atomicity):事務(wù)是一個(gè)原子操作單元,其對(duì)數(shù)據(jù)的修改,要么全都執(zhí)行,要么全都不執(zhí)行。(針對(duì)于操作層面)
? ??一致性(Consistent) :在事務(wù)開始和完成時(shí),數(shù)據(jù)都必須保持一致狀態(tài)。這意味著所有相關(guān)的數(shù)據(jù)規(guī)則都必須應(yīng)用于事務(wù)的修改,以保持?jǐn)?shù)據(jù)的完整性。(針對(duì)于數(shù)據(jù)層面)
? ??隔離性(Isolation) :數(shù)據(jù)庫系統(tǒng)提供一定的隔離機(jī)制,保證事務(wù)在不受外部并發(fā)操作影響的“獨(dú)立”環(huán)境執(zhí)行。這意味著事務(wù)處理過程中的中間狀態(tài)對(duì)外部是不可見的,反之亦然。
? ??持久性(Durable) :事務(wù)完成之后,它對(duì)于數(shù)據(jù)的修改是永久性的,即使出現(xiàn)系統(tǒng)故障也能夠保持。
二、并發(fā)事務(wù)帶來的問題
? ? 更新丟失或者臟寫(Lost Update):當(dāng)兩個(gè)事務(wù)或者多個(gè)事務(wù)對(duì)同一條數(shù)據(jù)做更新時(shí),后面提交的數(shù)據(jù)會(huì)覆蓋前面的寫數(shù)據(jù);
????臟讀(Dirty Reads):事務(wù)A讀取到了還未提交事務(wù)B的數(shù)據(jù);
? ? 不可重復(fù)讀(Non-Repeatable Reads):事務(wù)A和事務(wù)B同時(shí)begin時(shí),事務(wù)B先提交了,事務(wù)A讀取到了事務(wù)B已提交的數(shù)據(jù);
? ? 幻讀(Phantom Reads):事務(wù)A和事務(wù)B同時(shí)begin時(shí),事務(wù)B先提交了,事務(wù)A讀取到了事務(wù)B已提交的新增數(shù)據(jù);
三、事務(wù)的隔離級(jí)別

四、MVCC機(jī)制
讀已提交和可重復(fù)讀都是用了MVCC(Multi-Version Concurrency Control)機(jī)制;
首先mysql會(huì)為每一行數(shù)據(jù),多維護(hù)trx_id(事務(wù)id,一般是自增的)和roll_pointer(回滾指針,上一個(gè)版本的指針);再會(huì)維護(hù)一個(gè)undo日志,每當(dāng)數(shù)據(jù)有更新時(shí),先把歷史版本數(shù)據(jù)寫入undo日志,便于以后回滾;

MVCC機(jī)制:在事務(wù)開啟后,第一個(gè)查詢語句執(zhí)行之前,會(huì)把當(dāng)前數(shù)據(jù)庫存在的未提交事務(wù)放在一個(gè)readView集合中,獲取一個(gè)當(dāng)前數(shù)據(jù)庫最大的事務(wù)id(max_id);再從readView中選出最小的事務(wù)id(min_id);因?yàn)槭聞?wù)是自增的;所以當(dāng)事務(wù)開啟后,查詢到的數(shù)據(jù)
1.如果trx_id的版本號(hào)小于min_id則說明當(dāng)前這個(gè)版本號(hào)肯定是在我這個(gè)事務(wù)開啟前已提交的,則是可見的,可以查詢出來的數(shù)據(jù);
2.如果大于min_id且小于max_id,則需要去看是否在readView集合中,如果在該集合中,則該事務(wù)未提交,則是不可見的,需要根據(jù)roll_pointer去查找上個(gè)版本的數(shù)據(jù),直到查找到復(fù)核規(guī)則的數(shù)據(jù);
3.如果是大于max_id,因?yàn)槭聞?wù)id是自增的,則該事務(wù)肯定是我查詢之后才插入的數(shù)據(jù),所以該數(shù)據(jù)是不可見的,則需要查找上個(gè)版本數(shù)據(jù),直到查找到復(fù)核規(guī)則的數(shù)據(jù);
mysql默認(rèn)使用可重復(fù)讀級(jí)別,是上述規(guī)則;當(dāng)使用讀已提交,區(qū)別在于,每次查詢語句都會(huì)生成一個(gè)當(dāng)前的readView;