Msql-数据库死锁

实验案例

CREATE TABLE `t1_deadlock` (
`id` int(11) NOT NULL,
`name` varchar(100) DEFAULT NULL,
`age` int(11) NOT NULL,
`address` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `idx_age` (`age`) USING BTREE,
KEY `idx_name` (`name`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
Insert into t1_deadlock(id,name,age,address) values (1,'刘备',18,'蜀国');
Insert into t1_deadlock(id,name,age,address) values (2,'关羽',17,'蜀国');
Insert into t1_deadlock(id,name,age,address) values (3,'张飞',16,'蜀国');
Insert into t1_deadlock(id,name,age,address) values (4,'关羽',16,'蜀国');
Insert into t1_deadlock(id,name,age,address) values (5,'诸葛亮',35,'蜀国');
Insert into t1_deadlock(id,name,age,address) values (6,'曹孟德',32,'魏国');

案例1

Time Transaction1 Transaction2
T1 begin; begin;
T2 select * from t1_deadlock where id=1 for update;
T3 delete from t1_deadlock where id=5;
T4 update t1_deadlock set name=‘qqq’ where id=5;
T5 delete from t1_deadlock where id=1;
T6 死锁 死锁
-- Session01
begin;
select * from t1_deadlock where id=1 for update;
update t1_deadlock set name='qqq' where id=5;
commit;
-- Session02
begin;
delete from t1_deadlock where id=5;
delete from t1_deadlock where id=1;
-- 死锁
commit;

在这里插入图片描述
上图紫色表示当前事务持有的锁,红色表示需要等待花获取的锁。我们按照表中是执行顺序,首先事务1给1这条记录加了记录锁,然后事务2给5这条记录加了记录锁,这个时候事务1又想取更新记录5就需要等待事务2提交释放5的记录锁,同样事务2想要删除记录为1的数据也需要等待事务1提交释放1记录的锁。这样事务1等待事务2,事务2等待事务1就造成了死锁。

SHOW ENGINE INNODB STATUS;

在这里插入图片描述

案例2
Time Transaction1 Transaction2
T1 begin; begin;
T2 delete from t2_deadlock where cnt=‘abc-130-sz’;
T3 delete from t2_deadlock where cnt=‘abc-130-sz’;
T4 insert into t2_deadlock (cnt) values (‘abc-130-sz’);
T5 死锁 死锁
CREATE TABLE `t2_deadlock` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`cnt` varchar(32) DEFAULT NULL,PRIMARY KEY (`id`),
UNIQUE index `idx_cnt` (`cnt`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
insert into t1_deadlock03(id,cnt) values (1,'abc-130-sz');
``
```sql
-- Session01
begin;
delete from t2_deadlock where cnt='abc-130-sz';
insert into t2_deadlock(cnt) values ('abc-130-sz');
commit;
-- Session02
begin;
delete from t2_deadlock where cnt='abc-130-sz';
commit;

在这里插入图片描述
事务1持有了这条记录的写锁,然后插入的时候由于需要先当前读最新的数据,所以需要加读锁,但是写锁是排它的就需要等待写锁释放,但是写锁只有在事务提价的时候才会释放,因此产生了死锁。

在这里插入图片描述

如何避免死锁

MySQL默认会主动探知死锁,并回滚某一个影响最小的事务。等另一事务执行完成之后,再重新执行该事务。

  1. 注意程序的逻辑:根本的原因是程序逻辑的顺序交叠,最常见的是交差更新
  2. 保持事务的轻量:越是轻量的事务,占有越少的锁资源,这样发生死锁的几率就越小
  3. 提高运行的速度:避免使用子查询,尽量使用主键等等
  4. 尽量快提交事务,减少持有锁的时间:越早提交事务,锁就越早释放

相关推荐

  1. 预防 MySQL 的策略

    2024-02-07 15:56:03       28 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-02-07 15:56:03       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-02-07 15:56:03       101 阅读
  3. 在Django里面运行非项目文件

    2024-02-07 15:56:03       82 阅读
  4. Python语言-面向对象

    2024-02-07 15:56:03       91 阅读

热门阅读

  1. 鸿蒙 WiFi 扫描流程(1)

    2024-02-07 15:56:03       120 阅读
  2. LeetCode每日一题 | LCP 30. 魔塔游戏

    2024-02-07 15:56:03       50 阅读
  3. 没有事情做 随手写的小程序

    2024-02-07 15:56:03       58 阅读
  4. fgcvbnm

    fgcvbnm

    2024-02-07 15:56:03      51 阅读
  5. C#(C Sharp)学习笔记_Switch条件判断分支语句【六】

    2024-02-07 15:56:03       44 阅读
  6. 127. 单词接龙

    2024-02-07 15:56:03       59 阅读
  7. 【ESLint】TypeError:this.libOptions.parse is not a function

    2024-02-07 15:56:03       53 阅读
  8. 09-错误处理

    2024-02-07 15:56:03       38 阅读
  9. HarmonyOS NEXT 星河版项目案例

    2024-02-07 15:56:03       53 阅读