1.事情背景
背景由于更换新的短信供应商,同事之前可能对这块业务不太熟,原本是回执ID(recordId)一个手机号一个,但是同事接的时候将这个批量发送接口只设置了一个recordId,导致了多个手机号共用了一个recordId。
2.线上deadLock 事件发生
### Error updating database. Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException: Deadlock found when trying to get lock; try restarting transaction
- 先执行sql 语句查看执行计划,为什么存在锁竞争
UPDATE sms_send SET req_success = 2,err_msg = '状态成功' WHERE send_day = '20220323' AND phone_number = 'xxx' AND record_id = 'xxxx';

- 找DBA同学查找相关的死锁日志
死锁概念: 死锁是指两个或者多个事务在同一资源上相互占用,并请求锁定对方占用的资源,从而导致恶性循环的现象。当多个事务试图以不同的顺序锁定资源时,就可能会产生死锁
线上死锁日志如下: 平常很少开启长事务,并且为了减少死锁概率,线上的隔离级别为RC。(间隙锁只有在rr级别下才有,rc 级别是行锁)
------------------------
LATEST DETECTED DEADLOCK
------------------------
2022-03-23 10:19:11 0x7f8f9bf38700
*** (1) TRANSACTION:
TRANSACTION 2912167906, ACTIVE 0 sec fetching rows
mysql tables in use 3, locked 3
LOCK WAIT 48 lock struct(s), heap size 8400, 4 row lock(s)
MySQL thread id 16079756, OS thread handle 140261855196928, query id 2624577147
sms_user updating
UPDATE sms_send SET req_success = 2,err_msg = '状态成功' WHERE send_day = '20220323' AND phone_number = 'aaaaa' AND record_id = 'xxxxx'
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 56 page no 1943341 n bits 96 index PRIMARY of table `sms`.`sms_send` trx id 2912167906 lock_mode X locks rec but not gap waiting

本文分析了一起因短信供应商更换而导致的短信系统线上死锁事件。详细解释了死锁原因及涉及的SQL语句,展示了具体的死锁日志,并提出了改进措施。
最低0.47元/天 解锁文章
860

被折叠的 条评论
为什么被折叠?



