mysql可重復讀的幻讀解決方案

首先需要明確的就是“幻讀”概念:隔離級別是可重復讀,在一個事務中前后兩次查詢蒋腮,查到了其他事務insert進來的數(shù)據(jù)任连。
強調(diào)的是讀取到了其他事務插入進來的數(shù)據(jù)。
下面來論證一下可重復讀下幻讀的解決方案

# 建表語句
CREATE TABLE `test`  (
  `id` int(11) NOT NULL COMMENT '主鍵',
  `d` int(11) NOT NULL,
  `c` int(11) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_bin COMMENT = '測試表';
# 插入數(shù)據(jù)
INSERT INTO `test`(`id`, `d`, `c`) VALUES (0, 0, 0);
INSERT INTO `test`(`id`, `d`, `c`) VALUES (2, 2, 2);
INSERT INTO `test`(`id`, `d`, `c`) VALUES (3, 3, 3);
INSERT INTO `test`(`id`, `d`, `c`) VALUES (4, 4, 4);
INSERT INTO `test`(`id`, `d`, `c`) VALUES (5, 5, 5);
INSERT INTO `test`(`id`, `d`, `c`) VALUES (6, 6, 6);
INSERT INTO `test`(`id`, `d`, `c`) VALUES (7, 7, 7);
INSERT INTO `test`(`id`, `d`, `c`) VALUES (8, 8, 8);
INSERT INTO `test`(`id`, `d`, `c`) VALUES (9, 9, 9);
T1 T2 T3
begin; select * from TABLE where d = 5 for update;
update TABLE set d = 5 where id = 0;
select * from TABLE where d = 5 for update;
insert into TABLE values(1,5,1);
select * from TABLE where d = 5 for update; commit;

先明確一下球榆,for update語法就是當前讀,也就是查詢當前已經(jīng)提交的數(shù)據(jù)禁筏,并且是帶悲觀鎖的持钉。沒有for update就是快照讀,也就是根據(jù)readView讀取的undolog中的數(shù)據(jù)篱昔。

  • 當T1開啟事務每强,執(zhí)行第一條select語句時,查出來的結果如下:
id d c
5 5 5
  • 假如該查詢只鎖定一行州刽,也就是id=5的這一行數(shù)據(jù)空执,那么在T2階段id=0并不會被鎖定,那么update執(zhí)行成功后穗椅,id=0那行數(shù)據(jù)被設置為d=5辨绊。此時T1階段第二個select查詢結果如下:
id d c
5 5 5
0 5 0
  • T3階段執(zhí)行插入語句后,T1階段第三個查詢得出的結果如下:
id d c
5 5 5
0 5 0
1 5 1

如果按照以上猜想匹表,那么整個執(zhí)行結果就違背了可重復讀的隔離級別了门坷。


那么我們再假設select * from TABLE where d = 5 for update;這條語句鎖定的是所有被掃描到的數(shù)據(jù)宣鄙。

  • 按照上述執(zhí)行邏輯,我們在T1階段第一個select讀取到的數(shù)據(jù):
id d c
5 5 5
  • T1階段第二個select讀取到的數(shù)據(jù):
id d c
5 5 5

這是因為T2階段的update會被阻塞住默蚌,畢竟所有被掃描到的記錄都被鎖定了冻晤。

  • 但是在T3階段依然會執(zhí)行,T3階段做的是insert操作绸吸,本身這條記錄在表中都不存在的鼻弧,也就不會被阻塞。那么T1階段第三個select查詢結果如下:
id d c
5 5 5
1 5 1

按照上述推理過程惯裕,很顯然温数,即使鎖定所有掃描到的數(shù)據(jù)行,也依然存在幻讀的情況蜻势。違背了可重復讀的隔離級別撑刺。


針對這個情況,我們要解決幻讀的問題握玛,那么就要求針對所有被掃描的記錄行以及還不存在的d=5的記錄行都給鎖住够傍。

  • 在T1階段當執(zhí)行第一條select語句時,所有被掃描的記錄行都鎖住挠铲,包括d=5的不存在的記錄行冕屯。那么T2執(zhí)行的時候,就會被阻塞住拂苹,等待T1結束安聘。
id d c
5 5 5
  • 當執(zhí)行到T1階段的第二個select時,因為T2還在等待T1結束瓢棒,所以查詢結果一樣
id d c
5 5 5
  • 當執(zhí)行T3階段的insert語句時浴韭,因為所有d=5的不存在的記錄行也被鎖住了,也就是間隙被鎖住了脯宿,那么T3的insert語句也被阻塞念颈,等待T1結束。那么T1階段最后一條select語句執(zhí)行結果如下:
id d c
5 5 5

至此连霉,當前查詢結果完全滿足可重復讀的隔離級別榴芳。


通過以上推論,我們可以總結一下跺撼,在可重復讀的隔離級別下窟感,解決幻讀除了需要鎖定所有掃描到的記錄行外,還需要鎖定行之間的間隙歉井,也就是通過間隙鎖來解決幻讀的問題肌括。

?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子谍夭,更是在濱河造成了極大的恐慌,老刑警劉巖憨募,帶你破解...
    沈念sama閱讀 218,682評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件紧索,死亡現(xiàn)場離奇詭異,居然都是意外死亡菜谣,警方通過查閱死者的電腦和手機珠漂,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,277評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來尾膊,“玉大人媳危,你說我怎么就攤上這事「粤玻” “怎么了待笑?”我有些...
    開封第一講書人閱讀 165,083評論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長抓谴。 經(jīng)常有香客問我暮蹂,道長,這世上最難降的妖魔是什么癌压? 我笑而不...
    開封第一講書人閱讀 58,763評論 1 295
  • 正文 為了忘掉前任仰泻,我火速辦了婚禮,結果婚禮上滩届,老公的妹妹穿的比我還像新娘集侯。我一直安慰自己,他們只是感情好帜消,可當我...
    茶點故事閱讀 67,785評論 6 392
  • 文/花漫 我一把揭開白布棠枉。 她就那樣靜靜地躺著,像睡著了一般券犁。 火紅的嫁衣襯著肌膚如雪术健。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,624評論 1 305
  • 那天粘衬,我揣著相機與錄音荞估,去河邊找鬼。 笑死稚新,一個胖子當著我的面吹牛勘伺,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播褂删,決...
    沈念sama閱讀 40,358評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼飞醉,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起缅帘,我...
    開封第一講書人閱讀 39,261評論 0 276
  • 序言:老撾萬榮一對情侶失蹤轴术,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后钦无,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體逗栽,經(jīng)...
    沈念sama閱讀 45,722評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年失暂,在試婚紗的時候發(fā)現(xiàn)自己被綠了彼宠。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,030評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡弟塞,死狀恐怖凭峡,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情决记,我是刑警寧澤摧冀,帶...
    沈念sama閱讀 35,737評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站霉涨,受9級特大地震影響按价,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜笙瑟,卻給世界環(huán)境...
    茶點故事閱讀 41,360評論 3 330
  • 文/蒙蒙 一楼镐、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧往枷,春花似錦框产、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,941評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至屯碴,卻和暖如春描睦,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背导而。 一陣腳步聲響...
    開封第一講書人閱讀 33,057評論 1 270
  • 我被黑心中介騙來泰國打工忱叭, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人今艺。 一個月前我還...
    沈念sama閱讀 48,237評論 3 371
  • 正文 我出身青樓韵丑,卻偏偏與公主長得像,于是被迫代替她去往敵國和親虚缎。 傳聞我的和親對象是個殘疾皇子撵彻,可洞房花燭夜當晚...
    茶點故事閱讀 44,976評論 2 355

推薦閱讀更多精彩內(nèi)容