使INSERT ... SELECT语句原子

时间:2014-01-29 17:15:58

标签: mysql sql innodb

我有两个表:一个存储数据,另一个存储锁以指示用户何时对该数据进行操作。我想从第一个表中选择一些项目,以便它们匹配多个条件,并且在另一个表中没有相应的锁,然后将这些项的锁添加到第二个表。由于许多用户可能会同时尝试锁定项目,因此必须以原子方式完成此操作。

我已经编写了下面的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版本。

由于

修改

在进一步考虑之后,我意识到虽然锁定table1是不可接受的,但我可以锁定table2。因为我实际上无法在语句中锁定表(因为我必须锁定所有表,如果我选择锁定其中一个),我可以改为使用GET_LOCK创建一个互斥锁,防止多个进程同时调用此代码。我还没有机会测试这种方法,但感觉它可能比交易更轻量级。

1 个答案:

答案 0 :(得分:1)

没有。这就是交易的全部内容。他们在一个原子操作中组织了一堆语句,这些语句要么成功要么失败。

Here您可以找到乐观 pesimistic 锁定的一些解释,您可能会发现它很有用。 Here您可以找到有关InnoDB中使用的锁定机制的一些细节(pesimistic锁定)。 Here你可以找到关于如何在mysql中实现乐观锁定的指南。

希望我帮忙!