我正在使用InnoDB表执行SELECT ... FOR UPDATE
或行级锁定。
我的意图是只有一个请求可以读取同一行。因此,如果两个用户同时请求相同的数据。其中只有一个获取数据,首先触发查询。
但是我如何测试是否放置了锁定。因为我通过同时检索相同的数据并且两个用户都获取数据来测试它。
注意:我的表是InnoDB,我的查询在事务中执行,我的查询如下:
SELECT * FROM table_name WHERE cond FOR UPDATE;
我必须检查其他任何事情才能开始工作吗?
答案 0 :(得分:3)
打开2个mysql客户端会话。
在会话1:
mysql> start transaction;
mysql> SELECT * FROM table_name WHERE cond FOR UPDATE;
... (result here) ...
1 row in set (0.00 sec)
第2节:
mysql> start transaction;
mysql> SELECT * FROM table_name WHERE cond FOR UPDATE;
... (no result yet, will wait for the lock to be released) ...
返回会话1,以更新选定的记录(并释放锁):
mysql> UPDATE table_name SET something WHERE cond;
mysql> commit;
返回会话2:
1)显示锁定超时错误
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
2)或显示结果
... (result here) ...
1 row in set (0.00 sec)
3)或未显示任何结果(因为已修改相应的记录,因此不满足指定的条件)
Empty set (0.00 sec)
答案 1 :(得分:0)
您可以将自己的锁机制与lock_by列一起使用。
UPDATE table_name SET locked_by=#{proccess_id} WHERE cond and locked_by IS NULL
现在,在您的程序中,您将获得受影响的行数:
if(affected_rows==0)
return 'rows locked'
else
//do your staff with locked_by=#{process_id} rows
使用此机制,您可以控制锁定的行和锁定进程。您还可以添加UPDATE
语句locked_at=NOW()
以获取有关锁定行的更多信息。
不要忘记在locked_by
列上添加一些索引。
答案 2 :(得分:0)
以下是有关使用locks的MySQL文档。
在更新之前,你可以放锁,然后释放它。在另一个事务中,您可以使用唯一名称检查锁定。命名策略可以自己选择。