国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 數(shù)據(jù)庫 > MySQL > 正文

mysql 間隙鎖 Gap Lock

2024-07-24 12:35:49
字體:
供稿:網(wǎng)友
    MySQL InnoDB支持三種行鎖定方式:
 
  默認(rèn)情況下,InnoDB工作在可重復(fù)讀隔離級別下,并且以Next-Key Lock的方式對數(shù)據(jù)行進行加鎖,這樣可以有效防止幻讀的發(fā)生。Next-Key Lock是行鎖與間隙鎖的組合,這樣,當(dāng)InnoDB掃描索引記錄的時候,會首先對選中的索引記錄加上行鎖(Record Lock),再對索引記錄兩邊的間隙(向左掃描掃到第一個比給定參數(shù)小的值, 向右掃描掃描到第一個比給定參數(shù)大的值, 然后以此為界,構(gòu)建一個區(qū)間)加上間隙鎖(Gap Lock)。如果一個間隙被事務(wù)T1加了鎖,其它事務(wù)是不能在這個間隙插入記錄的。
 
  舉個例子:
 
  表task_queue
 
  Id           taskId
 
  1              2
 
  3              9
 
  10            20
 
  40            41
 
  開啟一個會話: session 1
 
  sql> set autocommit=0;
 
     ##
 
  取消自動提交
 
  sql> delete from task_queue where taskId = 20;
 
  sql> insert into task_queue values(20, 20);
 
  在開啟一個會話: session 2
 
  sql> set autocommit=0;
 
     ##
 
  取消自動提交
 
  sql> delete from task_queue where taskId = 25;
 
  sql> insert into task_queue values(30, 25);
 
  在沒有并發(fā),或是極少并發(fā)的情況下, 這樣會可能會正常執(zhí)行,在Mysql中, 事務(wù)最終都是穿行執(zhí)行, 但是在高并發(fā)的情況下, 執(zhí)行的順序就極有可能發(fā)生改變, 變成下面這個樣子:
 
  sql> delete from task_queue where taskId = 20;
 
  sql> delete from task_queue where taskId = 25;
 
  sql> insert into task_queue values(20, 20);
 
  sql> insert into task_queue values(30, 25);
 
  這個時候最后一條語句:insert into task_queue values(30, 25); 執(zhí)行時就會爆出死鎖錯誤。因為刪除taskId = 20這條記錄的時候,20 --  41 都被鎖住了, 他們都取得了這一個數(shù)據(jù)段的共享鎖, 所以在獲取這個數(shù)據(jù)段的排它鎖時出現(xiàn)死鎖。
 
  間隙鎖在InnoDB的唯一作用就是防止其它事務(wù)的插入操作,以此來達到防止幻讀的發(fā)生,所以間隙鎖不分什么共享鎖與排它鎖。另外,在上面的例子中,我們選擇的是一個普通(非唯一)索引字段來測試的,這不是隨便選的,因為如果InnoDB掃描的是一個主鍵、或是一個唯一索引的話,那InnoDB只會采用行鎖方式來加鎖,而不會使用Next-Key Lock的方式,也就是說不會對索引之間的間隙加鎖,仔細想想的話,這個并不難理解,大家也可以自己測試一下。
 
  要禁止間隙鎖的話,可以把隔離級別降為讀已提交,或者開啟參數(shù)innodb_locks_unsafe_for_binlog。

(編輯:武林網(wǎng))

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 黄浦区| 中超| 栾城县| 二手房| 通海县| 习水县| 于田县| 岚皋县| 通海县| 东辽县| 千阳县| 嵊泗县| 清徐县| 四会市| 卓资县| 灵宝市| 琼海市| 贵港市| 平谷区| 新宾| 房山区| 南和县| 凉城县| 泾源县| 花莲市| 略阳县| 屏南县| 盐池县| 安阳县| 马边| 荣昌县| 兖州市| 库尔勒市| 岢岚县| 济源市| 剑河县| 正宁县| 陇西县| 荔浦县| 罗源县| 葫芦岛市|