我举一个简单的例子来提出我面临的问题。考虑有两个事务试图使用
select for update
子句访问表中的某些行,如下所示:-
事务 1-
START TRANSACTION;
SELECT * FROM maas.model_requests where id='test1' and model_request_status='QUEUED' order by priority asc limit 1 for update;
事务 2 -
START TRANSACTION;
SELECT * FROM maas.model_requests where id='test2' and model_request_status='QUEUED' order by priority asc limit 1 for update;
COMMIT;
如您所见,两个事务都试图访问表的不同行
model_requests
id 在两个 where 子句中都是不同的。此外,我还没有提交第一个事务,以便检查 select for update 是否锁定了比预期更多的行。以上两个事务同时执行的结果是事务 2 永远无法获得锁定,即使事务 1 应该只锁定具有 id
的行作为 test1
.
现在,如果我从两个查询中删除 order by 子句,问题就会消失,即使事务 1 从未提交,事务 2 也会完成。我围绕这个尝试了一些谷歌搜索,发现类似的问题张贴在here。根据接受的答案,将参数
binlog_format
设置为 row
和 tx_isolation
到 read-committed
应该可以解决它。但即使设置了这些参数,它也没有为我解决。
需要注意的一件事是 where 子句中的两个列都是索引的一部分,我已经使用
explain
子句确认查询正在使用相同的索引。请建议如何解决这个问题。 Mysql版本是7.