自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

面試突擊:MVCC 和間隙鎖有什么區(qū)別?

開發(fā) 前端
在 MVCC 中,每個(gè)讀操作會(huì)看到一個(gè)固定版本的數(shù)據(jù)庫記錄,即使在并發(fā)環(huán)境中,也不會(huì)出現(xiàn)讀取到了其他事務(wù)還未提交的數(shù)據(jù)的情況。

MVCC 和間隙鎖是兩種完全不同的機(jī)制,但它們的目的都是相同的,都是用來保證數(shù)據(jù)庫并發(fā)訪問的,我們先來看二者的定義。

MVCC 定義

MVCC 是多版本并發(fā)控制(Multi-Version Concurrency Control)的縮寫,是一種并發(fā)控制的方法。

在 MVCC 中,每個(gè)讀操作會(huì)看到一個(gè)固定版本的數(shù)據(jù)庫記錄,即使在并發(fā)環(huán)境中,也不會(huì)出現(xiàn)讀取到了其他事務(wù)還未提交的數(shù)據(jù)的情況。

MVCC 通過保存數(shù)據(jù)在某個(gè)時(shí)間點(diǎn)的快照來實(shí)現(xiàn)這一點(diǎn)。在讀取數(shù)據(jù)時(shí),只會(huì)讀取在該時(shí)間點(diǎn)之前提交的數(shù)據(jù)。在寫入數(shù)據(jù)時(shí),會(huì)為每個(gè)寫入操作創(chuàng)建一個(gè)新版本的數(shù)據(jù),而不是直接覆蓋原有的數(shù)據(jù)。這樣,讀操作就可以讀取舊版本的數(shù)據(jù),而寫操作則可以寫入新版本的數(shù)據(jù),從而實(shí)現(xiàn)了并發(fā)控制。

在 MySQL 中,InnoDB 存儲(chǔ)引擎就是使用 MVCC 來實(shí)現(xiàn)并發(fā)控制的。

間隙鎖定義

間隙鎖是一種鎖定索引范圍而非實(shí)際數(shù)據(jù)的鎖,它可以鎖定一個(gè)范圍,防止其他事務(wù)在這個(gè)范圍內(nèi)插入數(shù)據(jù),從而保證了范圍內(nèi)的數(shù)據(jù)的唯一性。在 MySQL 中,InnoDB 存儲(chǔ)引擎支持間隙鎖。當(dāng)使用 SELECT ... FOR UPDATE 或 SELECT ... LOCK IN SHARE MODE 語句時(shí),InnoDB 存儲(chǔ)引擎會(huì)自動(dòng)使用間隙鎖來鎖定索引范圍。

如果一個(gè)事務(wù)在一個(gè)間隙上持有了鎖,那么其他事務(wù)就不能在這個(gè)間隙上插入數(shù)據(jù),但是可以在這個(gè)間隙之前或之后的位置插入數(shù)據(jù)。

為什么要有 MVCC?

既然已經(jīng)有鎖可以防止并發(fā)訪問了,那為什么還需要 MVCC 呢?MVCC 的誕生主要是出于性能的考慮,因?yàn)?MVCC 中沒有用到鎖,它是通過多版本并發(fā)控制的手段來實(shí)現(xiàn)數(shù)據(jù)庫并發(fā)訪問的,這樣相比于加鎖性能就會(huì)好很多。

MVCC 實(shí)現(xiàn)原理

MVCC 竟然這么強(qiáng),那它是怎么實(shí)現(xiàn)的呢?簡(jiǎn)單來說 MVCC 是通過以下 3 大組件實(shí)現(xiàn)的:

  1. 隱藏字段:每個(gè)執(zhí)行的 SQL 命令都有幾個(gè)隱藏的字段,其中有一個(gè)事務(wù) ID 字段,很重要。
  2. undo log(回滾日志):里面記錄了 SQL 命令執(zhí)行的歷史數(shù)據(jù)。
  3. Read View(讀視圖):包含快照讀(一個(gè)快照,保存了數(shù)據(jù)庫某個(gè)時(shí)刻的數(shù)據(jù))和一些重要的屬性。

它的實(shí)現(xiàn)原理簡(jiǎn)單來說,是通過 SQL 中隱藏的字段事務(wù) ID(自己的版本號(hào))和 Read View 中的屬性版本號(hào)進(jìn)行對(duì)比,對(duì)比之后決定使用 Read View 中的快照或 undo log 中的歷史數(shù)據(jù)(對(duì)比的規(guī)則是 MVCC 機(jī)制的規(guī)定,本文不展開討論),最后再將符合的數(shù)據(jù)返回。

MVCC 可以解決幻讀嗎?

幻讀是指在一個(gè)事務(wù)中,第一次查詢某個(gè)范圍的數(shù)據(jù)時(shí),發(fā)現(xiàn)有一些數(shù)據(jù)符合條件,但是當(dāng)再次查詢同樣的范圍時(shí),卻發(fā)現(xiàn)多了一些或者少了一些數(shù)據(jù)。這種情況就被稱為幻讀?;米x是由于并發(fā)事務(wù)中的數(shù)據(jù)修改操作導(dǎo)致的,比如在一個(gè)事務(wù)中,另一個(gè)事務(wù)插入了一條符合條件的數(shù)據(jù),導(dǎo)致第二次查詢時(shí)多了一條數(shù)據(jù)。

MVCC 機(jī)制可以解決部分幻讀問題,MVCC 是通過保存數(shù)據(jù)在某個(gè)時(shí)間點(diǎn)的快照來實(shí)現(xiàn)來解決(部分)幻讀問題的,在讀取數(shù)據(jù)時(shí),MVCC 會(huì)根據(jù)快照來確定可見的數(shù)據(jù)版本。這樣,即使其他事務(wù)在讀取數(shù)據(jù)時(shí)進(jìn)行了修改,也不會(huì)影響當(dāng)前事務(wù)的讀取結(jié)果。

因此,MVCC 可以有效地解決這部分幻讀問題。但需要注意的是,MVCC 只能解決讀取數(shù)據(jù)時(shí)的幻讀問題,對(duì)于寫入數(shù)據(jù)時(shí)的幻讀問題,還需要配合鎖機(jī)制或使用更高的事務(wù)隔離級(jí)別(串行化)來解決。

也就是說,想要徹底解決 MySQL InnoDB 中 RR(REPEATABLE READ,可重復(fù)讀)事務(wù)隔離級(jí)別的幻讀問題,需要使用 MVCC + 鎖機(jī)制共同來實(shí)現(xiàn)。

鎖分類

在 MySQL InnoDB 中的鎖機(jī)制不止有間隙鎖,還有行鎖和臨建鎖等。

行鎖、間隙鎖和臨建鎖有什么區(qū)別?

行鎖、間隙鎖和臨建鎖都是 MySQL 中的鎖機(jī)制,它們的區(qū)別如下:

  • 行鎖是針對(duì)某一行數(shù)據(jù)進(jìn)行的鎖定,可以防止其他事務(wù)修改該行數(shù)據(jù)。
  • 間隙鎖是針對(duì)某一范圍的數(shù)據(jù)進(jìn)行的鎖定,可以防止其他事務(wù)在該范圍內(nèi)插入數(shù)據(jù)。
  • 臨建鎖是行鎖和間隙鎖的組合,可以理解為一種特殊的間隙鎖,它等于行鎖+間隙鎖,除了鎖住記錄本身,還會(huì)鎖住索引之間的間隙,即鎖定一段左開右閉的索引區(qū)間。

小結(jié)

MVCC 和鎖機(jī)制解決了 MySQL InnoDB 中 RR 事務(wù)隔離級(jí)別的幻讀問題,而 MySQL 中的鎖類型又有很多種,如行鎖、間隙鎖、臨建鎖等。

最后

責(zé)任編輯:武曉燕 來源: Java中文社群
相關(guān)推薦

2022-05-09 07:37:04

Java非公平鎖公平鎖

2022-08-22 07:06:32

MyBatisSQL占位符

2022-08-03 07:04:56

GETHTTPPOST

2022-08-10 07:06:57

IoCDISpring

2022-04-24 07:59:53

synchronizJVMAPI

2022-02-08 07:02:32

進(jìn)程線程操作系統(tǒng)

2022-08-15 07:06:50

Propertiesyml配置

2022-04-26 08:02:00

locktryLocklockInterr

2022-10-09 20:52:19

事務(wù)隔離級(jí)別傳播機(jī)制

2022-03-16 07:33:40

守護(hù)線程用戶線程語言

2022-08-29 07:05:02

JSRJava語言

2022-01-11 06:53:23

面試重寫重載

2022-07-18 07:11:35

請(qǐng)求轉(zhuǎn)發(fā)請(qǐng)求重定數(shù)據(jù)共享

2023-02-17 08:02:45

@Autowired@Resource

2023-02-17 08:10:24

2023-02-01 07:15:16

2024-04-03 15:33:04

JWTSession傳輸信息

2024-09-19 08:42:43

2022-06-13 07:36:06

MySQLInnoDB索引

2024-09-24 13:49:13

SQL數(shù)據(jù)庫
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)