千家信息网

MySQL单表模拟锁的有哪些场景

发表于:2025-02-19 作者:千家信息网编辑
千家信息网最后更新 2025年02月19日,这篇文章主要介绍MySQL单表模拟锁的有哪些场景,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!在MySQL中对于并发,锁问题总是会有很多值得讨论的地方,但是通常来说,要模拟这些
千家信息网最后更新 2025年02月19日MySQL单表模拟锁的有哪些场景

这篇文章主要介绍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

直到事务超时才作罢。

以上是"MySQL单表模拟锁的有哪些场景"这篇文章的所有内容,感谢各位的阅读!希望分享的内容对大家有帮助,更多相关知识,欢迎关注行业资讯频道!

事务 数据 间隙 测试 场景 时候 级别 问题 死锁 隔离 还是 就是 情况 阻塞 意料之外 内容 效果 日期 篇文章 面的 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 网络安全 比特币病毒 我的世界服务器王国战争 集中器显示屏用什么软件开发 中职网络技术老师 国家知识产权专利数据库 科信网络技术 数据库发展历史分为几个阶段 国家udi数据库系统官网 网络技术服务咨询价钱 中国网络安全响应中心 如何将数据库导入到自己电脑 清明节网络安全专项保障 软件开发单一来源采购条件 县国税局 网络安全 上海睢变网络技术有限公司 西安齐全的软件开发信息推荐 大足区网络软件开发流程报价表 网络安全等级保护等级面试 网易手机版空岛生存服务器 杭州聚浪互联网科技有限公司 广东互联网云服科技有限公司 杭州宇鑫网络技术有限公司 网络安全意识和保密意识 安庆企业软件开发公司 福建mes软件开发 高中数据库管理技术pdf 网络安全趋势 2021 软件开发项目管理案例分析报告 安卓软件开发系统实例 网络安全公需课考试答案
0