<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      MySQL如何解決幻讀?

       

      • SERIALIZABLE 串行化
      • MVCC + Next-Key Lock

       

      幻讀:

        幻讀指事務T1在進行一次查詢之后發現某個記錄不存在,然后會根據這個結果進行下一步操作,此時如果事務T2成功插入了該記錄,那么對于事務T1而言,其進行下一步操作(比如插入該記錄)的時候很可能會報錯。從事務使用的角度來看,在檢查一條記錄不存在之后,其進行插入應該完全沒問題的,但是這里卻拋出主鍵沖突的異常。

      簡單來說:事務T1的兩次讀之間有其他事務寫操作,比如事務T1統計年齡 > 30,當T1兩次讀數據之間其他事務新添加了記錄,所以事務T1第二次讀取到的數據突然多了一個,仿佛出現了幻覺一般,這就是一種幻讀

       

      串行化:

      • 事務在讀操作時,先加共享鎖,直到事務結束才釋放
      • 事務在寫操作時,先加排它鎖,直到事務結束才釋放
      串行化隔離級別 是 MySQL 中最高級別的隔離模式,它確保每個事務按順序執行,就像在一個接一個的單線程環境中一樣。
      這意味著在同一時間只有一個事務可以訪問特定的數據集,從而徹底消除并發帶來的問題,如臟讀、不可重復讀和幻讀。

      隱式鎖機制

      在串行化隔離級別下,InnoDB 會自動為某些查詢施加隱式的 Next-Key Locks,即使這些查詢沒有顯式地使用 FOR UPDATE 或 LOCK IN SHARE MODE。這種隱式鎖機制確保事務按順序執行,并防止并發插入和更新操作。
      串行化使用間隙鎖(A>10,A是主鍵,則A<10的數據可以插入,A是一般索引,按B+樹葉子節點排列加間隙鎖)、行鎖(等值的讀寫時)、表鎖(當間隙鎖鎖住表所有記錄,插入間隙鎖范圍外的數據插入失敗),幻讀不存在的!!! 

       

      --------------------------------------------------------------------------------------------------------------------------------------------------------------------

       

      多版本并發MVCC:

      InnoDB 的 MVCC, 是 通過 在 每 行 記錄 后面 保存 兩個 隱藏 的 列 來 實現 的。 這 兩個 列, 一個 保存 了 行的 創建 時間, 一個 保存 行的 過期 時間( 或 刪除 時間)。 當然 存儲 的 并不是 實際 的 時間 值, 而是 系統 版 本號( system version number)。 每 開始 一個 新的 事務, 系統 版本 號 都會 自動 遞增。 事務 開始時 刻 的 系統 版 本號 會 作為 事務 的 版 本號, 用來 和 查詢 到 的 每 行 記錄 的 版本 號 進行 比較。

      MVCC 只在 REPEATABLE READ 和 READ COMMITTED 兩個 隔離 級別 下 工作。

      MVCC快照讀需滿足條件:

      1. InnoDB 只 查找 版本 早于 當前 事務 版本 的 數據 行( 也就是, 行的 系統 版本 號 小于 或 等于 事務 的 系統 版 本號), 這樣 可以 確保 事務 讀 取的 行, 要么 是在 事務 開始 前 已經 存在 的, 要么 是 事務 自身 插入 或者 修 改過 的。
      2. 行的 刪除 版本 要么 未定義, 要么 大于 當前 事務 版 本號。 這可 以 確保 事務 讀取 到 的 行, 在 事務 開始 之前 未被 刪除。

      MVCC解決了基于快照讀下的幻讀,事務 讀 取的 行, 要么 是在 事務 開始 前 已經 存在 的, 要么 是 事務 自身 插入 或者 修 改過 的。

      并不會讀到其他事務的寫操作 !!!

       

      MVCC無法解決當前讀下的幻讀。

       在 REPEATABLE READ 可重復讀的隔離級別下進行當前讀:

      1. 事務T1 INSERT id= 10的記錄,事務T2 在事務T1未commit時進行INSERT id=10的記錄會阻塞,

      對已COMMIT進行INSERT 會主鍵索引沖突 Duplicate entry '10' for key 'PRIMARY'。

      2. 可以顯式的加意向排它鎖、意向共享鎖避免大部分幻讀

      select * from tb where ? lock in share mode;
             select * from tb where ? for update;

      for update:IX鎖(意向排它鎖),即在符合條件的rows上都加了排它鎖

      lock in share mode:是IS鎖(意向共享鎖),即在符合條件的rows上都加了共享鎖

      排它鎖:X鎖、 寫鎖,事務A對一個資源加了X鎖后只有A本身能對該資源進行讀和寫操作,其他事務對該資源的讀和寫操作都將被阻塞,直到A釋放鎖為止  

      共享鎖:S鎖、 讀鎖, 事務A鎖定的數據其他事務可以共享讀該資源,但不能寫,直到事務A釋放

       

      FOR UPDATE 和 LOCK IN SHARE MODE 在可重復讀隔離級別下會查詢到其他事務已提交的數據。

       事務T1 

      start TRANSACTION;

      INSERT into orders (id,amount)  VALUES (2,100);

      COMMIT;

      事務T2

      start TRANSACTION;
      
      SELECT * FROM orders;
      
      SELECT * FROM orders FOR UPDATE;
        SELECT * FROM orders LOCK IN SHARE MODE;

       

      事務T1插入id=2的記錄后COMMIT成功,此時事務T2執行 SELECT * FROM orders; 在可重復讀的事務隔離級別下查詢不到id=2的數據記錄。

      但執行 SELECT * FROM orders FOR UPDATE; 或 SELECT * FROM orders LOCK IN SHARE MODE;  可以查詢到id=2的記錄

       
      若先執行事務T2的  SELECT * FROM orders FOR UPDATE; 獲取INNDB快照,且加間隙鎖。
      事務T1的DML語句會阻塞報錯。這樣就不會出現幻讀
      INSERT into orders (id,amount) VALUES (3,50);
      
      耗時:50006.079 ms執行結果:Error 1205 (HY000): Lock wait timeout exceeded; try restarting transaction [6aca72a3-5e65-466c-acea-1140658ffa94]

      -------------------------------------------------------------------------------------------------------------------------------------------------------

      間隙鎖Gap Lock:

      事務T1 鎖定 orders 表 amount 大于1的所有記錄

      start TRANSACTION;
      
      UPDATE orders SET amount = 200 WHERE amount > 1; 

       

      事務T2 執行INSERT 語句報錯 Lock wait timeout exceeded,等待事務T1進行事務COMMIT釋放鎖

      start TRANSACTION;
      
      INSERT into orders (id,amount)  VALUES (2,100);

      耗時:50008.956 ms執行結果:Error 1205 (HY000): Lock wait timeout exceeded; try restarting transaction [523d8451-a0ce-4e94-b7b7-3ad0f786ccb4]

       

      Next-Key Lock是Gap Lock(間隙鎖)和Record Lock(行鎖)的結合版,都屬于Innodb的鎖機制,主要應用于可重復讀隔離級別,但也可能出現在更高隔離級別的事務中。

      在某些情況下,即使使用 Next-Key Lock,也可能出現幻讀,特別是在非唯一索引上。

      select * from tb where id>100 for update;
      1. 主鍵索引 id 會給 id=100 的記錄加上 record行鎖
      2. 索引 id 上會加上 gap 鎖,鎖住 id(100,+無窮大)這個范圍

      其他事務對  id>100 范圍的記錄讀和寫操作都將被阻塞

      插入 id=1000的記錄時候會命中索引上加的鎖會報出事務異常;


      Next-Key Lock會確定一段范圍,然后對這個范圍加鎖,保證A在where的條件下讀到的數據是一致的,因為在where這個范圍其他事務根本插不了也刪不了數據,都被Next-Key Lock鎖堵在一邊阻塞掉了。

       

      施瓦茨(Baron Schwartz); 扎伊采夫(Peter Zaitsev); 特卡琴科(Vadim Tkachenko). 高性能MySQL(第3版)

       

      posted @ 2020-04-15 14:41  爪哇搬磚  閱讀(10236)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 国产精品国产三级国产试看| 激情自拍校园春色中文| 毛片网站在线观看| 亚洲中文字幕无码不卡电影| 成人av天堂网在线观看| 欧美乱妇狂野欧美在线视频 | 亚洲一本二区偷拍精品| 精品尤物TV福利院在线网站| 亚洲 日韩 在线精品| 亚洲男人的天堂av手机在线观看| 日韩av一区二区三区精品| 一面膜上边一面膜下边视频| 高h纯肉无码视频在线观看| 黄男女激情一区二区三区| 武隆县| 亚洲中文字幕精品第一页| 国产在线拍揄自揄拍无码视频| 欧美视频二区欧美影视| 中文国产不卡一区二区| 亚洲伊人久久精品影院| 极品人妻少妇一区二区三区| 日韩精品不卡一区二区三区| 亚洲av无码片在线播放| AV无码不卡一区二区三区| 国产麻传媒精品国产av| 国产精品一区二区三区麻豆| 国产成人无码一二三区视频| 国产av中文字幕精品| 亚洲另类激情专区小说图片| 91精品国产自产91精品| 亚洲国产美女精品久久久| 台南市| 岛国最新亚洲伦理成人| 蜜臀av无码一区二区三区| 欧美黑人又粗又大久久久| 亚洲 另类 小说 国产精品无码| 天堂V亚洲国产V第一次| 甘德县| brazzers欧美巨大| 精品国产线拍大陆久久尤物| 莲花县|