前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >InnoDB死锁示例

InnoDB死锁示例

作者头像
只喝牛奶的杀手
发布2019-08-26 16:33:30
4020
发布2019-08-26 16:33:30
举报

mysql如果需要支持事务的话,需要用InnoDB引擎,InnoDB用于事务处理应用程序,具有众多特性,包括ACID事务支持。如果应用中需要执行大量的INSERT或UPDATE操作,则应该使用InnoDB,这样可以提高多用户并发操作的性能。

InnoDB实现的两种类型行锁:S Lock (Shared lock, 共享锁)X Lock (Exclusive lock, 排他锁);

一般来说,读写操作的锁不同。读锁(或叫共享锁)允许并发线程读取加锁的数据,但禁止写数据。相反,写锁(或叫排他锁)阻止其他线程的读写操作。

以下示例说明了锁定请求导致死锁时如何发生错误。该示例涉及两个客户端,A和B.

首先,客户端A创建一个包含一行的表,然后开始一个事务。在事务中,A通过S在共享模式中选择它来获取该行的 锁定:

mysql> CREATE TABLE t (i INT) ENGINE = InnoDB;

Query OK, 0 rows affected (1.07 sec)

mysql> INSERT INTO t (i) VALUES(1);

Query OK, 1 row affected (0.09 sec)

mysql> START TRANSACTION;

Query OK, 0 rows affected (0.00 sec)

mysql> SELECT * FROM t WHERE i = 1 FOR SHARE;

+------+

| i |

+------+

| 1 |

+------+

接下来,客户端B开始一个事务并尝试从表中删除该行:

mysql> START TRANSACTION;

Query OK, 0 rows affected (0.00 sec)

mysql> DELETE FROM t WHERE i = 1;

删除操作需要X锁定。无法授予S锁定,因为它与客户端A持有的锁不兼容 ,因此请求将进入行和客户端B块的锁定请求队列。

最后,客户端A还尝试从表中删除该行:

mysql> DELETE FROM t WHERE i = 1;

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

try restarting transaction

此处发生死锁,因为客户端A需要 X锁定才能删除该行。但是,无法授予该锁定请求,因为客户端B已经有X锁定请求并且正在等待客户端A释放其S锁定。由于B事先要求锁定,因此SA所持有的锁也不能 升级 X为X锁。结果,

InnoDB为其中一个客户端生成错误并释放其锁定。客户端返回此错误:

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

try restarting transaction

此时,可以授予其他客户端的锁定请求,并从表中删除该行。

https://dev.mysql.com/doc/refman/8.0/en/innodb-deadlock-example.html

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-12-05,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 只喝牛奶的杀手 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云数据库 SQL Server
腾讯云数据库 SQL Server (TencentDB for SQL Server)是业界最常用的商用数据库之一,对基于 Windows 架构的应用程序具有完美的支持。TencentDB for SQL Server 拥有微软正版授权,可持续为用户提供最新的功能,避免未授权使用软件的风险。具有即开即用、稳定可靠、安全运行、弹性扩缩等特点。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档