我有两个表:一个存储数据,另一个存储锁以指示用户何时使用该数据。我想从第一个表中选择一些项目,以使它们符合多个条件,并且在另一个表中没有相应的锁定,然后将这些项目的锁定添加到第二个表格。由于许多用户可能会同时尝试锁定物品,因此有必要以原子方式完成此操作。将INSERT ... SELECT语句原子化为
我已经写了下面的SQL语句来尝试这样做,但我收到错误Deadlock found when trying to get lock;
。
INSERT INTO table2 (id, user, date)
SELECT id, ?, NOW()
FROM table1
LEFT JOIN table2 USING id
WHERE locked IS NULL AND <several conditions on table1>
ORDER BY date 'DESC'
LIMIT 15;
有什么办法可以使这个原子操作没有锁定表吗?目前我正在使用一个事务,如果它不成功,就重新尝试,但是我对这是否可以避免感兴趣。我在InnoDB上使用MySQL版本5.0.95。
感谢
编辑
已经给出一些这方面的进一步的思考,我意识到,虽然锁定表1是不可接受的,我可以锁定表2。由于我实际上无法锁定表中的表(因为如果选择锁定其中一个表,我必须锁定所有表),我可以使用GET_LOCK创建互斥锁,以防止多个进程同时调用此代码。我还没有机会测试这种方法,但感觉它可能是比事务更轻量级的解决方案。
与您的问题无关,但如果锁定是table2中的字段,则必须将其上的过滤器从where子句移至join子句。否则,你实际上有一个内部联接。 –
由于我不知道不同类型的连接,因此我肯定需要详细了解连接如何工作。如果第一个表中的大部分项目都有相应的锁,我认为您的建议可以提高性能?由于表2通常是空的,它是否提供任何其他好处? – tgt