java mysql实现原理_MySQL事务实现原理
MySQL事務(wù)隔離級(jí)別的實(shí)現(xiàn)原理
知識(shí)儲(chǔ)備
只有InnoDB支持事務(wù),所以這里說(shuō)的事務(wù)隔離級(jí)別是指InnoDB下的事務(wù)隔離級(jí)別
隔離級(jí)別
讀未提交:一個(gè)事務(wù)可以讀取到另一個(gè)事務(wù)未提交的修改。這會(huì)帶來(lái)臟讀,幻讀,不可重復(fù)讀問(wèn)題
讀已提交:一個(gè)事務(wù)只能讀取另一個(gè)事務(wù)已經(jīng)提交的修改。其避免了臟讀,仍然存在不可以重復(fù)讀和幻讀問(wèn)題
可重復(fù)讀:同一個(gè)事務(wù)中多次讀取相同的數(shù)據(jù)返回的結(jié)果是一樣的。其避免了臟讀和不可重復(fù)讀問(wèn)題,但是幻讀依然存在
串行化:事務(wù)串行之行。避免了以上所有問(wèn)題
以上是SQL-92標(biāo)準(zhǔn)中定義的四種隔離級(jí)別。在MySQL中,默認(rèn)的隔離級(jí)別是REPEATABLE-READ(可重復(fù)讀),并且解決了幻讀問(wèn)題。
不可重復(fù)讀重點(diǎn)在于Update和delete,而幻讀的重點(diǎn)在于insert
MVCC
MVCC的全稱(chēng)是多版本并發(fā)控制。MVCC使得InnoDB的事務(wù)隔離級(jí)別下執(zhí)行一致性讀操作有了保證。簡(jiǎn)單說(shuō)就是為了查詢(xún)一些正在被另一個(gè)事務(wù)更新的行,并且可以看到它們被更新之前的值。這是一個(gè)用來(lái)增強(qiáng)并發(fā)性的強(qiáng)大技術(shù),可以使得查詢(xún)不用等待另一個(gè)事務(wù)釋放鎖。
MVCC會(huì)給每一行增加三個(gè)字段。分別是DB-TRX-ID DB-ROLL-PTR,DB-ROW-ID
增刪查改
在InnoDB中,給每行增加兩個(gè)隱藏字段來(lái)實(shí)現(xiàn)MVCC,一個(gè)用來(lái)記錄數(shù)據(jù)行的創(chuàng)建時(shí)間,另一個(gè)用來(lái)記錄行的過(guò)期時(shí)間,在實(shí)際操作中,存儲(chǔ)的并不是時(shí)間,而是事務(wù)版本號(hào),每開(kāi)啟一個(gè)新事務(wù),事務(wù)的版本號(hào)就會(huì)遞增。所以增刪改查中對(duì)版本號(hào)的作用如下:
select:
讀取創(chuàng)建版本小于或等于當(dāng)前事務(wù)版本號(hào),并且刪除版本為空或大于當(dāng)前事務(wù)版本的記錄。這樣可以保證在讀取之前記錄都是存在的
insert:
將當(dāng)前事務(wù)的版本號(hào)保存至行的創(chuàng)建版本號(hào)
update
新插入一行,并以當(dāng)前事務(wù)版本號(hào)作為新行的創(chuàng)建版本號(hào),同時(shí)將原記錄行的刪除版本號(hào)設(shè)置為當(dāng)前事務(wù)版本號(hào)
delete
將當(dāng)前事務(wù)版本號(hào)保存至行的刪除版本號(hào)
快照讀和當(dāng)前讀
快照讀:讀取的是快照版本,也就是歷史版本
當(dāng)前讀:讀取的是最新版版
普通的select就是快照讀,而update,delete,insert,select...LOCK In SHARE MODE,SELECT...for update就是當(dāng)前讀
一致性非鎖定讀和鎖定讀
鎖定讀
在一個(gè)事務(wù)中,標(biāo)準(zhǔn)的SELECT語(yǔ)句是不會(huì)加鎖,但是有兩種情況例外。SELECT ... LOCK IN SHARE MODE 和 SELECT ... FOR UPDATE。
SELECT ... LOCK IN SHARE MODE:給記錄假設(shè)共享鎖,這樣其他事務(wù)職能讀不能修改,直到當(dāng)前事務(wù)提交
SELECT ... FOR UPDATE:給索引記錄加鎖,這種情況跟UPDATE的加鎖情況是一樣的
一致性非鎖定讀
consistent read(一致性讀),InnoDB用多版本來(lái)提供查詢(xún)數(shù)據(jù)庫(kù)在某個(gè)時(shí)間點(diǎn)的快照。如果隔離級(jí)別是REPEATABLE READ,那么在同一個(gè)事務(wù)中的所有一致性讀都讀的是事務(wù)中第一個(gè)的讀讀到的快照;如果是READ COMMITTED,那么一個(gè)事務(wù)中的每一個(gè)一致性讀都會(huì)讀到它自己刷新的快照版本。Consistent read(一致性讀)是READ COMMITTED和REPEATABLE READ隔離級(jí)別下普通SELECT語(yǔ)句默認(rèn)的模式。一致性讀不會(huì)給它鎖訪問(wèn)的表加任何形式的鎖,因此其他事務(wù)可以同時(shí)并發(fā)的修改它們
鎖
Record Locks(記錄鎖):在索引記錄上加鎖
Gap Locks(間隙鎖):在索引記錄之間加鎖,或者在第一個(gè)索引記錄之前加鎖,或者在最后一個(gè)索引記錄之后加鎖
Next-Key Locks:在索引記錄上加鎖,并且在索引記錄之前的間隙加鎖。相當(dāng)于Record Locks與Gap Locks的一個(gè)結(jié)合
假如一個(gè)索引包含以下幾個(gè)值:10,11,13,20.那么這個(gè)索引的next-key鎖將會(huì)覆蓋以下區(qū)間:
(negative infinity, 10]
(10, 11]
(11, 13]
(13, 20]
(20, positive infinity)
理論分析
在默認(rèn)的隔離級(jí)別中,普通的SELECT用的是一致性讀不加鎖。而對(duì)于鎖定讀,UPDATE和DELETE,則需要加鎖,至于加什么鎖是有不同情況的。如果對(duì)一個(gè)唯一索引使用了唯一的檢索條件,那么只需要鎖定相應(yīng)的索引記錄就好;如果是沒(méi)有使用唯一索引作為檢索條件,或者用到了索引范圍掃描,那么將會(huì)使用間隙鎖或者next-key鎖來(lái)以此阻塞其他會(huì)話(huà)向這個(gè)范圍內(nèi)的間隙插入數(shù)據(jù)
利用MVCC實(shí)現(xiàn)一致性非鎖定讀,保證在同一個(gè)事務(wù)中多次讀取相同的數(shù)據(jù)返回的結(jié)果是一樣的,解決了不可重復(fù)讀問(wèn)題
利用Gap Locks和Next-key可以阻止其他事務(wù)在鎖定區(qū)間內(nèi)插入數(shù)據(jù),解決了幻讀問(wèn)題
綜上所述,MySQL的默認(rèn)隔離級(jí)別的實(shí)現(xiàn)依賴(lài)于MVCC和鎖,準(zhǔn)確點(diǎn)說(shuō)就是一致性讀和鎖
https://www.cnblogs.com/develop-SZT/p/10339138.html
總結(jié)
以上是生活随笔為你收集整理的java mysql实现原理_MySQL事务实现原理的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 【FlexSim2019】自学笔记:20
- 下一篇: Visual Studio 2013 各