mysql第四篇文章~关于锁的那点事

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了mysql第四篇文章~关于锁的那点事相关的知识,希望对你有一定的参考价值。

一 简介:遇到被人请教了一个并行更新锁的问题,让我纠结了好一阵子,后来请教了高人,终于想通。

二 实验: 

    CREATE TABLE `test1` (
    `ID` varchar(36) NOT NULL COMMENT ‘ID‘,
    `NAME` varchar(36) DEFAULT ‘‘,
   `STATUS` varchar(10) DEFAULT NULL,
   `PID` varchar(36) DEFAULT NULL COMMENT ‘父级ID‘,
    PRIMARY KEY (`ID`),
    KEY `IDX_PID` (`PID`)
   ) ENGINE=InnoDB DEFAULT CHARSET=utf8
   insert into `test1` (`ID`, `NAME`, `STATUS`, `PID`) values(‘1‘,‘1‘,‘A‘,‘111‘);
   insert into `test1` (`ID`, `NAME`, `STATUS`, `PID`) values(‘2‘,‘3‘,‘B‘,‘222‘);
   insert into `test1` (`ID`, `NAME`, `STATUS`, `PID`) values(‘3‘,‘3‘,‘D‘,‘333‘);
   insert into `test1` (`ID`, `NAME`, `STATUS`, `PID`) values(‘4‘,‘4‘,‘E‘,‘222‘);
   insert into `test1` (`ID`, `NAME`, `STATUS`, `PID`) values(‘5‘,‘5‘,‘F‘,‘222‘);
   insert into `test1` (`ID`, `NAME`, `STATUS`, `PID`) values(‘6‘,‘6‘,‘C‘,‘111‘);
   事务1
   begin
   update test1 set name=‘2131‘ where pid=111;

   事务2
   begin
   update test1 set name=‘21311‘ where id=3;

   结果 在执行事务1的时候 事务2 会卡住(pid为非唯一性索引,id为主键)

  三 分析:

   通过分析得出以下几点

   1 数据库模式 :RR 

   2 数据库对于非唯一性索引的加锁方式:1 寻找到这条记录的主键索引进行这条记录的锁定 record lock(针对指定记录的更新和删除),  2对于非唯一性索引本身上下值的范围的锁定,gap lock(针对指定范围的插入)

  四 疑惑 :

     按照理论分析来说,事务1的锁定记录只有ID=1和ID=6这两条记录和相关的gap锁,不应该会阻塞事务2 ID=3的更新。纠结了好久好久,又问了很多人 

  五 解决 :

     终于得到了M哥和文兄的指点才发现,更新语句的类型是varchar,而我两个事务的条件都没加引号。。,导致了隐式转换(还是粗心惹的祸),条件加上引号后,不会阻塞了。解决。

  六 补充
     1 隐式转换会导致索引失效,切记切记

     2 关于非唯一性索引锁定的范围一定要判断好

       

      




















以上是关于mysql第四篇文章~关于锁的那点事的主要内容,如果未能解决你的问题,请参考以下文章

关于缓存一致性协议MESIStoreBufferInvalidateQueue内存屏障Lock指令和JMM的那点事

关于缓存一致性协议MESIStoreBufferInvalidateQueue内存屏障Lock指令和JMM的那点事

关于电源的那点事

Linux中的RCU的那点事

python与中文的那点事

UIScrollview 与 Autolayout 的那点事