[用事实说明两个凡是]一个mysql莫名锁表的问题

只愿长相守 提交于 2019-12-04 13:32:34

背景

上回书<<一个由mysql事务隔离级别造成的问题分析>>说到, 有两个实例去更新一条记录, 一条成功, 一条失败. 成功的认为自己获取到的记录, 于是 开开心心的把任务进行处理, 但是在他试图将任务状态更新为处理成功时, 去发现任务被别人锁了...

具体问题

抢到任务的进程

2015-11-23 19:42:01|INFO|exec_task.php|40||get one task: 11
...
//开始处理
2015-11-23 19:42:01|INFO|exec_task.php|107||line_count: 9
2015-11-23 19:42:01|INFO|exec_task.php|147||fork child success: 8346
2015-11-23 19:42:01|INFO|exec_task.php|264||[0] pid: 8346, start: 0, stop: 0

2015-11-23 19:42:01|INFO|exec_task.php|147||fork child success: 8347
2015-11-23 19:42:01|INFO|exec_task.php|264||[1] pid: 8347, start: 1, stop: 1

2015-11-23 19:42:01|INFO|exec_task.php|147||fork child success: 8348
2015-11-23 19:42:01|INFO|exec_task.php|264||[2] pid: 8348, start: 2, stop: 2

2015-11-23 19:42:01|INFO|exec_task.php|147||fork child success: 8349
2015-11-23 19:42:01|INFO|exec_task.php|264||[3] pid: 8349, start: 3, stop: 3

2015-11-23 19:42:01|INFO|exec_task.php|147||fork child success: 8350
2015-11-23 19:42:01|INFO|exec_task.php|264||[4] pid: 8350, start: 4, stop: 4
...
2015-11-23 19:42:01|INFO|exec_task.php|159||child procss exit ,start to merge result file
//处理结束,更新状态,结果发现等待锁超时
2015-11-23 19:42:52|ERR|function.inc.php|113||SQL fail: Lock wait timeout exceeded; try restarting transaction

没有抢到任务的进程

2015-11-23 19:42:51|INFO|function.inc.php|100||task_id 11 is locked by another process, get next task
2015-11-23 19:42:51|INFO|function.inc.php|100||task_id 11 is locked by another process, get next task
2015-11-23 19:42:52|INFO|function.inc.php|100||task_id 11 is locked by another process, get next task
2015-11-23 19:42:52|INFO|function.inc.php|100||task_id 11 is locked by another process, get next task
2015-11-23 19:42:52|INFO|function.inc.php|100||task_id 11 is locked by another process, get next task
2015-11-23 19:42:52|INFO|function.inc.php|100||task_id 11 is locked by another process, get next task
2015-11-23 19:42:52|INFO|function.inc.php|100||task_id 11 is locked by another process, get next task
2015-11-23 19:42:52|INFO|function.inc.php|100||task_id 11 is locked by another process, get next task
2015-11-23 19:42:52|INFO|function.inc.php|100||task_id 11 is locked by another process, get next task
2015-11-23 19:42:52|INFO|function.inc.php|100||task_id 11 is locked by another process, get next task
2015-11-23 19:42:52|INFO|function.inc.php|100||task_id 11 is locked by another process, get next task
2015-11-23 19:42:52|INFO|function.inc.php|100||task_id 11 is locked by another process, get next task
....
2015-11-23 19:42:52|INFO|function.inc.php|100||task_id 11 is locked by another process, get next task
2015-11-23 19:42:53|INFO|function.inc.php|100||task_id 11 is locked by another process, get next task
2015-11-23 19:42:53|INFO|function.inc.php|100||task_id 11 is locked by another process, get next task
2015-11-23 19:42:53|INFO|function.inc.php|100||task_id 11 is locked by another process, get next task
2015-11-23 19:42:53|INFO|function.inc.php|100||task_id 11 is locked by another process, get next task

即由于没有抢到任务的进程在2015-11-23 19:42:52的时候,正在死循环, 事务没有提交, 把记录给锁了, 所以抢到任务的进程 想把记录更新的时候, 出现等待锁超时.

一个事务没有提交,把记录锁了, 导致另一个事务无法更新, 听起来很正常对吧.

请注意, 没有抢到任务的进程并没有更新到task_id = 11的记录,却把这个记录锁了.

问题重现

这个问题其实很好重现. 见以下操作记录:

表结构

create database if not exists ae;
create table ae.task (
id int primary key,
status int);

操作记录1操作记录2

问题综述

在两个事务同时更新同一条记录的情况下, 一个事务因另一个事务将记录修改导致的条件不满足而更新不成功, 更新不成功的事务还是会把这条记录锁住.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!