1.2 READ COMMITTED(讀已提交)

1.設(shè)置為讀已提交

SET GLOBAL TRANSACTION ISOLATION LEVEL READ COMMITTED;

2.此時TA執(zhí)行插入,并查詢,可以查詢到結(jié)果

3.TB不能查到結(jié)果

證明已經(jīng)不能讀到未提交的數(shù)據(jù)

但是仍然存在不可重復(fù)讀問題 (同一事務(wù)內(nèi)兩次讀的數(shù)據(jù)不一致)

4.為了演示效果,把用戶數(shù)據(jù)插入數(shù)據(jù)庫并提交,此時表中有一條id為1的 name為aaa的記錄

TB開啟一個事務(wù) 并進(jìn)行查詢

5.此時TA進(jìn)行數(shù)據(jù)修改,并提交

6.B再次查詢可以看到A事務(wù)已經(jīng)提交的結(jié)果

根據(jù)測試可以發(fā)現(xiàn),先開啟的事務(wù)TA在事務(wù)TB提交之前進(jìn)行的查詢和TB提交之后進(jìn)行的第二次查詢,兩次查詢結(jié)果不一致,出現(xiàn)不可重復(fù)讀情況。

如果要避免不可重復(fù)讀,至少要把事務(wù)隔離級別設(shè)為:1.3 REPEATABLE READ(可重復(fù)讀)

InnoDB采用了MVCC(Multiversion Concurrency Control)多版本并發(fā)控制,避免不可重復(fù)讀。MVCC只在 READ COMMITTED? 和 REPEATABLE READ? 2個隔離級別下工作。MVCC會建立多個ReadView,RC是語句級多版本(事務(wù)的多條只讀語句,創(chuàng)建不同的ReadView,代價更高),RR是事務(wù)級多版本(一個事務(wù)有一個ReadView)。由于RC中未提交的事務(wù),不允許其他事務(wù)看到,但是本身事務(wù)需要看到,所以執(zhí)行多條語句時,都需要建立新的ReadView,以支持本事務(wù)后面的查詢。

注:

MVCC本意應(yīng)該是下面的樣子:

每行數(shù)據(jù)都存在一個版本,每次數(shù)據(jù)更新時都更新該版本

修改時Copy出當(dāng)前版本隨意修改(類似于Java并發(fā)包中的CopyOnWrie操作),各個事務(wù)之間無干擾

保存時比較版本號,如果成功(commit),則覆蓋原記錄;失敗則放棄copy(rollback)

但是InnoDB的實(shí)現(xiàn)有一些差別:

事務(wù)以排他鎖的形式修改原始數(shù)據(jù)

把修改前的數(shù)據(jù)存放于Undo log,通過回滾指針與主數(shù)據(jù)關(guān)聯(lián)

修改成功(commit)啥都不做,失敗則恢復(fù)Undo log中的數(shù)據(jù)(rollback)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容