浅谈MySQL 有哪些死锁场景
作者:萧木易 发布时间:2024-01-13 13:45:54
首先一起来复习一下死锁的概念:死锁是指两个或者多个事务在同一资源上相互占用,并请求锁定对方占用的资源,从而导致恶性循环的现象。
下面我们通过几个实验,来验证几种死锁场景。
1 环境准备
use martin;
drop table if exists dl;
CREATE TABLE `dl` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`a` int(11) NOT NULL,
`b` int(11) NOT NULL,
`c` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `idx_c` (`a`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE `dl_insert` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`a` int(11) NOT NULL,
`b` int(11) NOT NULL,
`c` int(11) NOT NULL,
PRIMARY KEY (`id`),
unique key `uniq_a` (`a`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
insert into dl(a,b,c) values (1,1,1),(2,2,2);
drop table if exists dl_1;
create table dl_1 like dl;
insert into dl_1 select * from dl;
2 同一张表下的死锁
session1 | session2 |
begin; | begin; |
select * from dl where a=1 for update;…1 row in set (0.00 sec) | select * from dl where a=2 for update;…1 row in set (0.00 sec) |
select * from dl where a=2 for update;/* SQL1 */(等待) | |
(session2 提示死锁回滚后,SQL1 成功返回结构) | select * from dl where a=1 for update;ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction |
commit; | commit; |
session1 在等待 session2 释放 a=2 的行锁,而 session2 在等待 session1 释放 a=1 的行锁。两个 session 互相等待对方释放资源,就进入了死锁状态。
3 不同表下的死锁
session1 | session2 |
begin; | begin; |
select * from dl where a=1 for update; … 1 row in set (0.00 sec) | select * from dl_1 where a=1 for update; … 1 row in set (0.00 sec) |
select * from dl_1 where a=1 for update;/* SQL2 */ 等待 | |
(session2 提示死锁回滚后,SQL1 成功返回结构) | select * from dl where a=1 for update; ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction |
commit; | commit; |
这个实验也是两个 session 互相等待对方释放资源,就进入了死锁状态。
4 间隙锁下的死锁
session1 | session2 |
set session transaction_isolation='REPEATABLE-READ'; /* 设置会话隔离级别为 RR */ | set session transaction_isolation='REPEATABLE-READ'; /* 设置会话隔离级别为 RR */ |
begin; | begin; |
select * from dl where a=1 for update; … 1 row in set (0.00 sec) | select * from dl where a=2 for update; … 1 row in set (0.00 sec) |
insert into dl(a,b,c) values (2,3,3);/* SQL1 */ 等待 | |
(session2 提示死锁回滚后,SQL1 成功返回结果) | insert into dl(a,b,c) values (1,4,4);/* SQL2 */ ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction |
commit; | commit; |
由于 RR 隔离级别下存在间隙锁,可以知道 SQL1 需要等待 a=2 获得的间隙锁,而 SQL2 需要等待 a=1 获得的间隙锁,两个 session 互相等待对方释放资源,就进入了死锁状态。
5 INSERT 语句的死锁
session1 | session2 | session3 |
begin; | ||
insert into dl_insert(a,b,c) value (3,3,3); | ||
insert into dl_insert(a,b,c) value (3,3,3);/* 等待 */ | insert into dl_insert(a,b,c) value (3,3,3);/* 等待 */ | |
rollback; | 执行成功 | ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction |
这里需要注意的是,a 字段有唯一索引。当 session1 执行完 insert 语句,会在索引 a=3 上加记录锁,当 session2 执行同样的 insert 语句时,唯一键冲突,加上读锁;同样 session3 也会加上读锁。
当 session1 回滚,session2 和 session3 都试图继续执行插入操作,都要加上写锁。此时两个 session 都要等待对方的行锁,因此出现了死锁。
一些死锁场景就介绍到这里,当然,也欢迎各位补充其他的一些死锁场景。
来源:https://blog.csdn.net/weixin_43997319/article/details/124983655
猜你喜欢
- 码代码时,有时候需要根据比较大小分别赋值:import randomseq = [random.randint(0, 1000) for _
- 在 AbpBase.Database 中,通过 Nuget 添加以下几个库:版本都是 1.9.0-preview0917
- 目录需求描述步骤分析和前置知识代码实现写在最后需求描述手上现有若干份财务分析报告的Word文档,如下:每一份Word文档中的内容如下:为了方
- 需求:Python检测URL状态,并追加保存200的URL代码一:#! /usr/bin/env python#coding=utf-8im
- 一、Mysql事务概念MySQL 事务主要用于处理操作量大,复杂度高的数据。由一步或几步数据库操作序列组成逻辑执行单元,这系列操作要么全部执
- 背景在写代码过程中,如果有频繁重复性的编码操作,或者可以Reuse的各类代码,可以通过Python写一个脚本,自动生成这类代码,就不用每次手
- 很多朋友问到sql server数据库”生成脚本”,只导出了数据库的sql脚本,而表里的数据依然没有导出来。很简单,看教程:注:我这里用的S
- 实例076:做函数题目:编写一个函数,输入n为偶数时,调用函数求1/2+1/4+...+1/n,当输入n为奇数时,调用函数1/1+1/3+.
- go-ini的分区go-ini的多个配置项通过分区(section)来划分。有默认(空)分区和命名的分区,没有给分区命名就是默认分区,默认分
- 一、Python 操作 Excel 的常用库小伙伴你好,在开始操作 Excel 之前,你需要安装 Python 和一些相关库。可以使用 pi
- 有时候,我们需要替换指定标签外的内容,而保留标签里面的内容不替换。比如当我们要在浏览器中显示出编辑器显示的原始格式时、需要将普通换行符“\n
- 方法一、线程池执行的循环代码为自己写的情况定义一个全局变量,默认为T,当QT界面关闭后,将该变量值改为F。线程执行的循环代码内增加一个判断方
- 前言PDO扩展为PHP访问数据库定义了一个轻量级的、一致性的接口,它提供了一个数据访问抽象层,这样,无论使用什么数据库,都可以通过一致的函数
- 有时候我们用的一些pdf资料是没有目录的,这样找寻我们想到的东西比较麻烦。本篇文章就为大家带来python来生成pdf目录书签的方法。首先,
- 函数重载的替代方法-伪重载,下面看一个具体的实例代码。<? php//函数重载的替代方法-伪重载////确实,在PHP中没有函数重载这
- 在Keras中有两种深度学习的模型:序列模型(Sequential)和通用模型(Model)。差异在于不同的拓扑结构。序列模型 Sequen
- 前言Tensorflow的核心与NumPy非常相似,但具有GPU支持;Tensorflow支持分布式计算(跨多个设备和服务器)。像NumPy
- 相信大家都试过将Python文件进行打包,来发给其他没有安装Python环境的用户使用,但通常情况下,打包生成的exe文件都很大,而产生这种
- 之前看到过很多头条,说哪国某人坚持了多少年自学使用excel画画,效果十分惊艳。 对于他们的耐心我十分敬佩。 但是作为一个程序员,自然也得挑
- 以下列出了两种数据库的方法:ASP+Access20001.要获取的ID值字段属性必须设为:自动编号(我们假设字段名为recordID)2.