Mysql死锁

本文深入探讨了MySQL死锁的产生原因及案例分析,详细解释了死锁的四个必要条件,并通过转账场景模拟了死锁的发生过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在学习的过程中,遇到了一个问题,MySQL死锁是如何产生的,今天,带着这个疑问来探讨下。

什么是死锁?

两个线程在互相同时等待对方释放资源。即:进程A战友资源R1,等待进程B占有的资源R2;进程B占有资源R2,等待进程A占有的资源R1.而且资源R1和R2只允许一个进程占用,不能亮哥进程同时占用。结果就是两个进程都不能继续执行,若不采取其他措施,这种循环等待的情况会一直持续下去,就发生了进程死锁。

死锁产生的必要条件?
  • 互斥条件

某个资源在一段时间内只能有一个进程占有,不能同时被两个或两个以上的进程占有。

  • 不可抢占条件

进程所获得到的资源在未使用完毕之前,资源申请这不能强行地从资源占有这手中夺取资源,只能有该资源占有者进程自行释放。

  • 占有且申请条件

进程至少已经占有一个资源,但又能申请新的资源,由于该资源已被另外进程占有,此时该进程阻塞,但是在等待新资源是,仍然可以占用已占有的资源。

  • 循环等待条件

存在一个进程等待序列{P1,P2,…Pn},其中P1等待P2所占有的某一资源,P2等待P3所占有的某一资源,。。。形成一个进程循环等待链。

MySQL中产生死锁的典型案例

在做交易系统的时候,都会遇到转账的问题,A用户转100元给B账户,这种情况下就有可能存在死锁问题。
模拟死锁产生:
开启两个Mysql数据库会话:

新建一张表:
CREATE TABLE `test`  (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT ' ',
  `name` varchar(64) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
)
会话一:
	
1.	BEGIN;
2.	SELECT * FROM test1 WHERE id = 1 FOR UPDATE;
3.	SELECT * FROM test1 WHERE id = 2 FOR UPDATE;
4.	COMMIT;

会话二:
1.	BEGIN;
2.	SELECT * FROM test1 WHERE id = 1 FOR UPDATE;
3.	SELECT * FROM test1 WHERE id = 2 FOR UPDATE;
4.	COMMIT;

上述代码中,先执行会话一的1.2.语句。然后在切换到会话二执行1.3.语句。
然后在执行会话一的3语句。最后执行会话二的2语句。此时就会发生异常:

1213 - Deadlock found when trying to get lock; try restarting transaction

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值