MySQL单表模拟锁的几个场景

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,高可用系列 2核4GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介:   在MySQL中对于并发,锁问题总是会有很多值得讨论的地方,但是通常来说,要模拟这些锁或者一些锁的问题需要花点功夫,比如创建多个表,创建大量的数据,然后像调试钟表的秒针一样,让问题刚好复现在哪个时间点上。

  在MySQL中对于并发,锁问题总是会有很多值得讨论的地方,但是通常来说,要模拟这些锁或者一些锁的问题需要花点功夫,比如创建多个表,创建大量的数据,然后像调试钟表的秒针一样,让问题刚好复现在哪个时间点上。如果换一个角度,单表来模拟这类而是可以吗,其实是可行的。

   今天简单通过单表的测试模拟死锁,事务中的隐式提交(其实可以理解是个bug),间隙锁。

初始化数据

首先的准备工作就是初始化数据,我们创建一个表test,事务隔离级别为默认的RR。

建表语句:

create table test(

id int not null ,

name int ,

primary key(id),

unique key(name)

) engine=innodb;

事务隔离级别:

mysql> show variables like '%isolation%';

+---------------+-----------------+

| Variable_name | Value           |

+---------------+-----------------+

| tx_isolation  | REPEATABLE-READ |

+---------------+-----------------+

1 row in set (0.00 sec)

除此之外就是打开两个窗口,我们简称为会话1,会话2.

模拟死锁


我们开始先模拟一下死锁问题。

会话1:

我们开启一个事务,插入一行记录,数据就选做今天的日期吧。

mysql>begin;

mysql> insert into test values(2017,827);

Query OK, 1 row affected (0.01 sec)


会话2;

mysql> insert into test values(2016,827);

这个时候会话2会阻塞,这个时候有一种特殊的情况,那就是阻塞超时,如果超时,会自动停止。


会话1:

mysql> insert into test values(2018,826);

Query OK, 1 row affected (0.00 sec)


可见会话1中的DML操作依旧是可以的。


会话2:

mysql> insert into test values(2016,827);

ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction

如果看会话2的情况,就会发现产生了死锁。

如果要尝试事务隔离级别RC,其实表现的效果是一样的。

仔细看看这个操作的过程就会发现,还是蛮“奇怪”的,数据之间彼此没有直接的依赖关联,怎么会产生死锁,这个里面有银式锁升级,还有间隙锁的一些东西,留给大家思考吧。


模拟意料之外的事务自动提交

为了基于上面的测试数据,让两条数据成功插入,我们在会话2中结束事务。

mysql>commit;

然后开始做意料之外的事务自动提交测试,这一次我们在同一个会话中测试即可。问题的背景是如果我们显式声明事务,在同一会话中做了DML操作,没有提交,如果再开启一个事务,之前的事务会自动提交。

会话1:

这是基于场景1的测试之后的数据情况。


mysql> select *from test;

+------+------+

| id   | name |

+------+------+

| 2018 |  826 |

| 2017 |  827 |

+------+------+

2 rows in set (0.00 sec)

我们显式声明一个事务。

mysql> begin;

Query OK, 0 rows affected (0.02 sec)

然后插入一条记录,重新给一个日期。

mysql> insert into test values(2019,825);

Query OK, 1 row affected (0.00 sec)

这个时候没有提交,我们在当前会话中重新再开启一个事务。

mysql > begin;

mysql > insert into test values(2015,830);


这个时候如果在会话2中查看,其实会发现,事务已经帮你提交了。

mysql> select *from test;

+------+------+

| id   | name |

+------+------+

| 2018 |  826 |

| 2017 |  827 |

+------+------+

2 rows in set (0.00 sec)


在会话1我们继续回滚事务,会发现于事无补。

mysql> rollback;

Query OK, 0 rows affected (0.01 sec)

这个时候数据已经自动提交了一部分。

mysql> select *from test;

+------+------+

| id   | name |

+------+------+

| 2018 |  826 |

| 2017 |  827 |

+------+------+

2 rows in set (0.00 sec)


间隙锁测试

上面的测试场景其实还是多多少少都有些关联,其中第一个场景和间隙锁也有关系,我就简单用单表模拟一下间隙锁。

首先还是保证事务隔离级别是RR,因为间隙锁是RR隔离级别特供,RC中就没有间隙锁这样的定制,在并发场景中还是有不小的影响。我们来看看效果。


会话1:

mysql> begin;

Query OK, 0 rows affected (0.00 sec)

指定数据范围,然后显示声明。

mysql> select id from test where id <2019 lock in share mode;

+------+

| id   |

+------+

| 2018 |

| 2017 |

+------+

2 rows in set (0.00 sec)


会话2:

会话2中也开启一个事务,插入一条记录。结果就被阻塞了。

mysql> begin;

Query OK, 0 rows affected (0.00 sec)

mysql> insert into test values(2016,829);

ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

直到事务超时才作罢。


 


相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。 &nbsp; 相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/mysql&nbsp;
目录
相关文章
|
4月前
|
SQL AliSQL 关系型数据库
MYSQL的全局锁和表锁
本文介绍了MySQL中的锁机制,包括全局锁、表级锁及其应用场景。全局锁通过`Flush tables with read lock (FTWRL)`实现,主要用于全库逻辑备份,但会阻塞更新和结构变更操作。表级锁分为显式表锁(`lock tables`)和元数据锁(MDL),前者用于控制并发访问,后者自动加锁以确保读写正确性。文章还探讨了如何安全地为小表添加字段,建议通过设置DDL等待时间或使用MariaDB/AliSQL的NOWAIT/WAIT功能避免业务阻塞。这些方法有助于在高并发场景下优化数据库性能与安全性。
110 0
|
3月前
|
关系型数据库 MySQL 分布式数据库
Super MySQL|揭秘PolarDB全异步执行架构,高并发场景性能利器
阿里云瑶池旗下的云原生数据库PolarDB MySQL版设计了基于协程的全异步执行架构,实现鉴权、事务提交、锁等待等核心逻辑的异步化执行,这是业界首个真正意义上实现全异步执行架构的MySQL数据库产品,显著提升了PolarDB MySQL的高并发处理能力,其中通用写入性能提升超过70%,长尾延迟降低60%以上。
|
11月前
|
SQL 关系型数据库 MySQL
MySQL 锁
MySQL里常见的几种锁
178 3
|
11月前
|
存储 关系型数据库 MySQL
MySQL在企业内部应用场景有哪些
【10月更文挑战第17天】MySQL在企业内部应用场景有哪些
422 0
|
11月前
|
存储 关系型数据库 MySQL
介绍一下MySQL的一些应用场景
【10月更文挑战第17天】介绍一下MySQL的一些应用场景
2399 0
|
7月前
|
关系型数据库 MySQL 网络安全
如何排查和解决PHP连接数据库MYSQL失败写锁的问题
通过本文的介绍,您可以系统地了解如何排查和解决PHP连接MySQL数据库失败及写锁问题。通过检查配置、确保服务启动、调整防火墙设置和用户权限,以及识别和解决长时间运行的事务和死锁问题,可以有效地保障应用的稳定运行。
313 25
|
8月前
|
存储 关系型数据库 MySQL
MySQL进阶突击系列(06)MySQL有几种锁?| 别背答案,现场演示一下
本文详细解析了MySQL InnoDB存储引擎的锁机制,涵盖读锁、写锁、意向锁、记录锁、间隙锁和临键锁等8种锁类型。重点探讨了不同锁类型的加锁与释放方式,以及事务并发场景下的实战验证。通过具体示例,展示了在不同情况下锁的行为及其对事务的影响。文章还特别强调了锁的作用范围主要是索引,并解释了锁如何影响数据的读写操作。最后总结了并发事务中加锁规则,帮助读者深入理解MySQL的锁机制。
|
11月前
|
存储 关系型数据库 MySQL
优化 MySQL 的锁机制以提高并发性能
【10月更文挑战第16天】优化 MySQL 锁机制需要综合考虑多个因素,根据具体的应用场景和需求进行针对性的调整。通过不断地优化和改进,可以提高数据库的并发性能,提升系统的整体效率。
586 1
|
11月前
|
存储 关系型数据库 MySQL
MySQL锁,锁的到底是什么?
【10月更文挑战第16天】MySQL 锁锁定的是与数据和资源相关的对象,其目的是为了保证数据的一致性、避免冲突,并在并发环境下合理协调事务或操作的执行。理解锁的对象和意义对于优化数据库性能、处理并发问题至关重要。
296 0
|
11月前
|
关系型数据库 MySQL 数据库
mysql锁详解
通过理解并合理运用MySQL中的锁机制,开发者可以有效管理数据库并发访问,平衡性能与数据一致性需求。更多关于MySQL锁的深入探讨和最佳实践,请参考专业的数据库管理资源[[深入MySQL锁机制详解
214 0

推荐镜像

更多