面试题如何解决幻读.docxVIP

  1. 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
  2. 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  3. 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  4. 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  5. 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  6. 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  7. 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
面试题-如何处理幻读 session A 在 T1 时辰就声明白,“我要把全部 d=5 的行锁住,不准别的事务进行读写操作”。而实际上,这个语义被破坏了。 2.2 数据全都性问题 锁的设计是为了保证数据的全都性。而这个全都性,不止是数据库内部数据形态在此刻的全都性,还包含了数据和日志在规律上的全都性。 候 binlog 里面的内容: 1) T2 时辰,session B 事务提交,写入了两条语句; 2)T4 时辰,session C 事务提交,写入了两条语句; 3)T6 时辰,session A 事务提交,写入了 update t set d=100 where d=5 这条语句。 放在一起如下: update t set d=5 where id=0; /*(0,0,5)*/update t set c=5 where id=0; /*(0,5,5)*/ insert into t values(1,1,5); /*(1,1,5)*/ update t set c=5 where id=1; /*(1,5,5)*/ update t set d=100 where d=5;/* 全部 d=5 的行,d 改成 100*/ 这个语句序列,不论是拿到备库去执行,还是以后用 binlog 来克隆一个库,这三行的结果,都变成了 (0,5,100)、(1,5,100) 和 (5,5,100)。 缘由是: 这是我们假设“select * from t where d=5 for update 这条语句只给d=5 这一行,也就是 id=5 的这一行加锁”导致的。 进一步假设: 把扫描过程中遇到的行,也都加上写锁,再来看看执行效果 binlog 里面执行序列: insert into t values(1,1,5); /*(1,1,5)*/update t set c=5 where id=1; /*(1,5,5)*/ update t set d=100 where d=5;/* 全部 d=5 的行,d 改成 100*/ update t set d=5 where id=0; /*(0,0,5)*/ update t set c=5 where id=0; /*(0,5,5)*/ 这里处理了session B的问题,但是session C新增的问题并没有处理! 在 T3 时辰,我们给全部行加锁的时候,id=1 这一行还不存在,不存在也就加不上锁。也就是说,即便把全部的记录都加上锁,还是阻挠不了新插入的记录。 3.InnoDB 怎样处理幻读的问题 产生幻读的缘由是,行锁只能锁住行,但是新插入记录这个动作,要更新的是记录之间的“间隙”。因而,为了处理幻读问题,InnoDB 只好引入新的锁,也就是间隙锁 (GapLock)。 间隙锁,锁的就是两个值之间的空隙。比如表 test_20,初始化插入了 6 个记录,这就产生了 7 个间隙。 当你执行 select * from t where d=5 for update 的时候,就不止是给数据库中已有的 6个记录加上了行锁,还同时加了 7 个间隙锁。这样就确保了无法再插入新的记录。 数据行是可以加上锁的实体,数据行之间的间隙,也是可以加上锁的实体。但是间隙锁跟我们之前遇到过的锁都不太一样。 跟行锁有冲突关系的是“另外一个行锁”。 跟间隙锁存在冲突关系的,是“往这个间隙中插入一个记录”这个操作。间隙锁之间都不存在冲突关系。 如下:这里 session B 并不会被堵住。由于表 test_20里并没有 c=7 这个记录,因而 session A 加的是间隙锁 (5,10)。而 session B 也是在这个间隙加的间隙锁。它们有共同的目标,即:爱护这个间隙,不允许插入值。但,它们之间是不冲突的。 间隙锁和行锁合称 next-key lock,每个 next-key lock 是前开后闭区间。也就是说,表test_20初始化以后,假如用 select * from t for update 要把整个表全部记录锁起来,就构成了 7 个next-key lock,分别是 (-∞,0]、(0,5]、(5,10]、(10,15]、(15,20]、(20, 25]、(25,+suprenum]。 把间隙锁记为开区间,把 next-keylock 记为前开后闭区间。 3.1 带来的问题 1)session A 执行 select ... for update 语句,由于 id=9 这一行并不存在,因而会加上间隙锁 (5,10); 2)session B 执行 select ... for update 语句,同样会加上间隙锁 (5,10),间隙锁之间不会冲突,因而这个语句可以执行成功; 3)session B 试

文档评论(0)

136****7795 + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档