日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

mysql 面试知识点笔记(七)RR如何避免幻读及非阻塞读、范式

發布時間:2023/12/6 数据库 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 mysql 面试知识点笔记(七)RR如何避免幻读及非阻塞读、范式 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

2019獨角獸企業重金招聘Python工程師標準>>>

表象:快照讀(非阻塞讀)--偽MVCC (Multi-Version Concurrent Controll多版本并發控制)

內在:next-key鎖(record鎖+gap鎖) rr serializabel 都支持gap鎖

問:在rr下對主鍵索引或者唯一索引會用gap鎖嘛?

如果where條件全部命中,則不會用gap鎖,只會加record鎖(行鎖)

如果部分命中或全不命中則會加gap鎖

比如查詢id in(1,3,5) ,id是主鍵。?查到了 1、3 ,沒有查到5則會加gap鎖,在3~+∞的區間。

如果加鎖是主鍵之外的索引 則會在當前索引以及主鍵索引上都上排他鎖。如下圖:

-- 創建測試表 CREATE TABLE `tb`( `name` varchar(10) NOT NULL, `id` int(100) NOT NULL DEFAULT '0', PRIMARY KEY(`name`), UNIQUE KEY `unique_id` (`id`) ) ENGINE = INNODB DEFAULT CHARSET=utf8;

插入以下數據:

不加gap鎖的情況

-- 第一個會話 SELECT @@tx_isolation; set SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;start TRANSACTION; DELETE from tb where id = 9; -- 執行完delete之后執行事務2的insert 是成功的 因為id=9存在 只加了行鎖 ROLLBACK;-- 第二個會話 SELECT @@tx_isolation; set SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;start TRANSACTION; insert into tb VALUES('i',10); ROLLBACK;

加gap鎖的情況

-- 1、全不命中 -- 第一個會話 start TRANSACTION; DELETE from tb where id = 7; -- 這里在執行事務2的insert 則會block 證明加了gap鎖 ROLLBACK;-- 第二個會話 start TRANSACTION; insert into tb VALUES('i',8); ROLLBACK;-- 2、部分命中情況 -- 第一個會話 start TRANSACTION; -- 這里命中5和9 7沒有命中 在6~8加了gap鎖 如果是in (5,6,9) 則不會加gap鎖 select * from tb where id in (5,7,9) lock in share mode; ROLLBACK;-- 第二個會話 start TRANSACTION; -- 沒有block insert into tb VALUES('i1',4); -- 有block insert into tb VALUES('i2',7); -- 有block insert into tb VALUES('i3',8); -- 沒有block insert into tb VALUES('i4',10); ROLLBACK;
  • Gap鎖還會用在非唯一索引或者不走索引的當前讀中
    • 非唯一索引都是到點的左開右閉區間

    測試表 非唯一索引

    CREATE TABLE `tb1`( `name` varchar(10) NOT NULL, `id` int(100) NOT NULL DEFAULT '0', PRIMARY KEY(`name`), KEY `non_unique_id` (`id`) ) ENGINE = INNODB DEFAULT CHARSET=utf8;

    -- 第一個會話 start TRANSACTION; DELETE from tb1 where id = 9; -- 此時執行會話2的insert 會被block ROLLBACK;-- 第二個會話 start TRANSACTION; insert into tb1 VALUES('test',9); #6-11的左開右閉區間 -- 不會block insert into tb1 VALUES('test1',5); -- 會block insert into tb1 VALUES('test2',7); -- 不會block insert into tb1 VALUES('test3',12); -- bb是主鍵c的左邊 所以不會block insert into tb1 VALUES('bb',6); -- dd是主鍵c的右邊 所以會block insert into tb1 VALUES('dd',6); -- e是主鍵f的左邊 所以不會block insert into tb1 VALUES('e',11); -- g是主鍵f的右邊 所以會block insert into tb1 VALUES('g',11); ROLLBACK;
    • 不走索引(會對所有的gap加鎖 就是鎖表了)

    測試表 無索引

    CREATE TABLE `tb2`( `name` varchar(10) NOT NULL, `id` int(100) NOT NULL DEFAULT '0', PRIMARY KEY(`name`) ) ENGINE = INNODB DEFAULT CHARSET=utf8;

    -- 第一個會話 start TRANSACTION; DELETE from tb2 where id = 9; ROLLBACK;-- 第二個會話 start TRANSACTION; -- 鎖表 這里的insert是block的 insert into tb2 VALUES('test',2); ROLLBACK;

    MySQL InnoDB非阻塞式讀的實現原理:MVCC

    MySQL InnoDB使用MVCC來實現非阻塞式讀,在這個模式下,數據庫會為每個數據記錄維護多個版本。在可重復讀隔離級別下,事務第一次查詢記錄的時候,會記錄下一個時間點,在該事務內如果再次(可是以不同的SELECT)查詢相同的數據的話,事務只會取時間點前的記錄版本,這樣在不需要對數據加鎖的情況下就實現了可重復讀的隔離級別了,而且并發性能更好。在同一事務內多次查詢同一數據,也不是就返回一個固定的記錄版本,如果事務先查詢了某個記錄,隨后自己又更新了這個數據,等再查詢該數據的話,返回的就是自己更新過后的數據版本了。此處來自:https://ouyanggod.iteye.com/blog/2165668

    范式參考:https://www.cnblogs.com/gdwkong/p/9012262.html

    轉載于:https://my.oschina.net/pentakill/blog/3045452

    總結

    以上是生活随笔為你收集整理的mysql 面试知识点笔记(七)RR如何避免幻读及非阻塞读、范式的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。