InnoDB的行锁,原来为你做了这么多( 三 )

  • 因为事务B回滚 , 所以事务B持有的间隙锁被释放 , 所以之前事务A的插入语句不再阻塞 , 顺利执行插入操作 。
  • ?
    报错信息:Deadlock found when trying to get lock; try restarting transaction
    ?
    用图把这个过程描述出来:
    InnoDB的行锁,原来为你做了这么多

    文章插图
     
    死锁过程
    最终结果事务A插入成功 , 事务B因为死锁被回滚 。
    总结间隙锁主要还是用于防止幻读的情况 , 所以多个事务能够同时获取同一段间隙锁本身并没有问题 , 间隙锁能够阻塞插入意向锁也并没有问题 。
    而插入意向锁可以看成是一种特殊的间隙锁 , 是用于在同一个间隙 , 插入不同的数据 , 不会互相阻塞 。它比普通间隙锁的数据一致性更低 , 但并发性能更好;
    解决思路普通间隙锁还是主要用于读操作防止幻读 。所以我们在想进行插入操作的时候 , 其实没有必要对即将插入的间隙使用普通间隙锁 , 直接使用insert语句产生的插入意向锁就好了 。
    如果要保证数据的一致性 , 可以使用插入意向锁配合主键、唯一键等约束 。
    附录那些在文章中用过的SQL:
    -- 建表create table demo( id int unsigned not null, c int unsigned not null, d int unsigned not null, constraint demo_pkprimary key (id), constraint idx_cunique (c));-- 插数据INSERT INTO demo VALUES(5, 5, 5),(10, 10, 10),(15, 15, 15),(20, 20, 20),(25, 25, 25);-- 禁止自动提交事务SET AUTOCOMMIT = 0;-- 开启事务BEGIN;-- 提交事务COMMIT;-- 会获取锁的查询SELECT * FROM demo WHERE id < 5 FOR UPDATE ;关于作者我是Yasin , 一个不断精进的菜鸡 。
    微信公众号:编了个程
    个人网站:https://yasinshaw.com
    关注我的公众号 , 和我一起成长~




    推荐阅读