Mysql之隔離級別

RC隔離級別

  1. RC 的本質就是事務中每一條 SELECT 語句均可以看到其他已提交事務對數據的修改,那麼只要該事物已經提交其結果就是可見的,與這兩個事務開始的先後順序無關,不完全適用於 MVCC 讀

RR隔離級別

  1. RR 的本質是從第一個 SELECT 語句生成 ReadView 開始,任何已經提交過的事務的修改均可見

幻讀

  1. 事務T1讀取了滿足某條件的一個數據集,事務T2插入了一行或者多行數據滿足了T1的選擇條件,導致事務T1再次使用同樣的選擇條件讀取的時候,得到了比第一次讀取更多的數據集。

實驗

  1. 準備數據

    
    DROP TABLE IF EXISTS `t_test`;
    CREATE TABLE `t_test` (
      `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
      `a` varchar(10) CHARACTER SET utf8 NOT NULL,
      `b` varchar(10) CHARACTER SET utf8 NOT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
    
    
    BEGIN;
    INSERT INTO `t_test` VALUES (1, 'a1', 'b1');
    INSERT INTO `t_test` VALUES (2, 'a1', 'b2');
    INSERT INTO `t_test` VALUES (3, 'a2', 'b3');
    INSERT INTO `t_test` VALUES (4, 'a3', 'b4');
    COMMIT;
    
    
  2. 幻讀演示一,不會產生幻讀

    image-20190909131707444

  3. 幻讀演示二,會產生幻讀

    image-20190909132005622

  4. 幻讀演示三,會產生幻讀

    image-20190909132851374

  5. 在RR級別中,數據是可重複讀,對於這種讀取歷史數據的方式,叫做快照讀(snapshot read),讀取數據庫當前版本數據的方式,叫當前讀 (current read)。

    • 快照讀就是普通的select
      • select * from table
    • 當前讀:特殊的讀操作,插入/更新/刪除操作,屬於當前讀,處理的都是當前的數據,需要加鎖
      • select * from table where xxx lock in share mode;
      • select * from table where xxx for update
      • Insert into
      • update
      • delete
  6. 在快照讀情況下,mysql通過mvcc(多版本併發控制)來避免幻讀。在當前讀讀情況下,mysql通過next-key來避免幻讀。

    select * from t where a=1;屬於快照讀
    select * from t where a=1 lock in share mode;屬於當前讀
    在RR級別下,如果是快照讀,那麼其實是可以避免幻讀的。如果是快照讀+當前讀,那麼其實是不能避免幻讀的
    
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章