记一次mysql数据库死锁问题分析--详解数据库innodb lock机制

本文详细分析了一次由于InnoDB锁机制引发的MySQL数据库死锁问题,探讨了非唯一索引列在删除操作时如何触发next-key lock,导致死锁。解决方案包括检查数据是否存在、分步处理事务以及调整事务隔离级别。同时,文章深入讲解了InnoDB的锁类型,如共享锁、排他锁、意图锁、记录锁、Gap Locks和Next-Key Locks。
摘要由CSDN通过智能技术生成

目录

  • 概述
  • 问题重现与解析
  • Innodb lock机制

概述

    正在奋力写"BUG"中,同事说出现死锁了,让帮忙看一下,so 放下手中工作,去瞅瞅, 一段很简单的代码,就是mysql数据库下使用多线程先删除数据再插入数据,造成了死锁

     顺便骗个赞,觉得写的还可以的,不要吝啬你的赞哟

问题重现与解析

    代码

205749_e3Vd_2342969.png

205912_2b15_2342969.png

    代码解释:

    第一张图,同事采用发令枪,多线程批量处理一批数据

    第二张图是批量处理数据的逻辑, 在一个事务中,先删除一条数据然后再插入一批数据

    异常提示

     堆栈异常: Deadlock found when trying to get lock; try restarting transaction;  意思很明了,就是尝试获取锁时发现死锁.

    疑惑

    这段代码做删除时,使用的索引列,凭直观理解,这应该只是个行级锁, 不应该会出现死锁的,看代码很清楚的理解到,每个线程持有一个事务操作,如果是行级锁肯定不会出现死锁,所以删除的时候肯定不止锁了一条数据

    拨云见日

    在生产环境中mysql的存储引擎绝大部分是 InnoDB ,为什么使用 InnoDB 呢? 点击查看详细答案, 就凭事务安全这一条,相信足以让选择InnoDb了。

    代码中delete操作的是非唯一索引列在innoDB引擎下会触发 next-key lock(间隙锁)。

    举例: 表t中有非唯一索引列 test_id为 1, 10, 18, 22, 26的5条数据,此时模拟操作:

事务A 删除一条不存在的数据,数据库就会去找从左开始找最近的索引值

delete from t where test_id= 27;

  事务B 删除一条不存在的数据,数据库就会去找从左开始找最近的索引值

delete from t where test_id= 28;

此时事务A和B就会分别产生一个(26,正无穷)间隙锁,然后继续操作

事务A

INSERT INTO t VALUES(27);

此时事务A阻塞,因为事务B在删除操作时拥有了区间锁 

事务B</

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值