您的位置:首页 > 数据库 > MySQL

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

2015-11-26 16:08 627 查看

背景

上回书
<<一个由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);






问题综述

在两个事务同时更新同一条记录的情况下, 一个事务因另一个事务将记录修改导致的条件不满足而更新不成功,
更新不成功的事务还是会把这条记录锁住.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: