Mysql死锁相关测试--DEMO

测试用表

CREATE TABLE `t` (
  `id` int(11) NOT NULL,
  `c` int(11) DEFAULT NULL,
  `d` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `id_c` (`c`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
INSERT INTO `t` VALUES ('0', '0', '0');
INSERT INTO `t` VALUES ('5', '5', '5');
INSERT INTO `t` VALUES ('10', '10', '10');
INSERT INTO `t` VALUES ('15', '15', '15');
INSERT INTO `t` VALUES ('20', '20', '20');
INSERT INTO `t` VALUES ('25', '25', '25');

开启两个会话。一般死锁都是发生在长事务中的。
模拟死锁
事务A的所有操作
在这里插入图片描述
事务B的所有操作
在这里插入图片描述
时序流程

  1. 事务A begin 事务B begin
  2. 事务A 执行select 对 5,15 加读锁 事务B 对 10 20 加读锁
  3. 事务B 想要修改id = 15 也就是对15加写锁。此时事务B会被阻塞。
  4. 事务A 想要修改id = 10 对10加写锁,此时事务A回滚。

分析:
事务A如果不回滚会怎样?
事务A持有 5 15 读锁,事务B持有 10 20 读锁
事务B 要去获取 5的写锁 事务A要获取 10的写锁。

完全满足了死锁的四个必要条件

  1. 互斥占有共享资源
  2. 不可剥夺
  3. 循环并等待
  4. 持有并等待

Mysql解决就是
1、让一个影响少的事务回滚
2、 超时等待。

补充一下上面死锁的产生的前提条件

  1. 读锁和写锁是互斥的
  2. 事务中锁的两阶段提交
    1. 需要查询或者修改的时候才加锁
    2. 事务结束的时候释放锁

为什么要用两阶段锁?
我搜到的是为了解决隔离性,并发事务中保证事务的调度正确。

一般长事务更加容易导致死锁的发生。要避免长事务死锁的发生,怎么避免?

  1. 尽量将锁的获取放到事务的后面,减少锁等待时间
  2. 控制并发度
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值