如何在mysql中执行check-and-insert?

时间:2017-11-06 08:32:23

标签: mysql multithreading locking

在我的代码中,我需要执行以下操作:

  

检查MySQL表(InnoDB)是否存在特定行(符合某些条件)。如果是,请将其退回。如果没有,请创建它,然后将其返回。

我似乎遇到的问题是竞争条件。每隔一段时间,两个进程就会紧密地运行在一起,它们同时检查表,不看行,并且都插入它 - 因此重复数据。

我正在阅读MySQL文档,试图想出一些方法来防止这种情况发生。我到目前为止所做的事情:

  • 唯一索引似乎是一种选择,但它们并不是通用的(只有当条件对所有行都是唯一的时候才有效)。
  • 即使在SERIALIZABLE级别的交易也不会阻止INSERT,期间。
  • SELECT ... LOCK IN SHARE MODESELECT ... FOR UPDATE
  • LOCK TABLE ... WRITE可以做到,但这是一个非常激烈的措施 - 其他进程无法从表中读取,我需要锁定我打算使用的所有表直到我解锁它们。

基本上,我想要执行以下任一操作:

  • 在允许INSERT / SELECT的情况下阻止表格中的所有UPDATE进入表格(这可能是不可能的,因为它在大多数情况下都没有意义)。< / LI>
  • 组织某种手动锁定。这两个过程将相互协调,哪个进行选择/插入舞蹈,而另一个进行等待。这需要某种操作,等待锁释放。我可以实现一个自旋锁(一个进程反复检查对方是否释放了锁),但我担心它会占用大量资源。

1 个答案:

答案 0 :(得分:0)

我想我自己找到了答案。 InnoDB表中的事务+ SELECT ... FOR UPDATE可以提供同步锁(也就是互斥锁)。让所有进程在开始工作之前锁定特定表中的特定行。然后只有一个能够一次运行,其余的将等到第一个完成其交易。