MySQL:如何保持锁定并使其他线程等待尚未插入的插入';还没有发生

MySQL:如何保持锁定并使其他线程等待尚未插入的插入';还没有发生,mysql,sql,multithreading,locking,Mysql,Sql,Multithreading,Locking,我面临着一个看似简单的问题,但却很难解决。我们希望记录每次收到营销(潜在客户)的情况,这样我们在90天内不会购买超过一次。许多潜在客户提供商可以多次向我们提供相同的潜在客户,通常是同时提供。我们想返回一个“接受”给一个潜在供应商 那么,让我们来谈谈有效的场景:我们在过去90天内看到了材料,并在表上记录了一条记录,有3家供应商同时展示了潜在客户: select count(id) from recent_leads where last_seen_at >= '2019-10-11 0

我面临着一个看似简单的问题,但却很难解决。我们希望记录每次收到营销(潜在客户)的情况,这样我们在90天内不会购买超过一次。许多潜在客户提供商可以多次向我们提供相同的潜在客户,通常是同时提供。我们想返回一个“接受”给一个潜在供应商

那么,让我们来谈谈有效的场景:我们在过去90天内看到了材料,并在表上记录了一条记录,有3家供应商同时展示了潜在客户:

select count(id) from recent_leads where 
  last_seen_at >= '2019-10-11 00:00:00' 
  and email = 'yes@example.com' for update;
Thread1首先到达,并获取锁。MySQL返回到Thread1:

+-----------+
| count(id) |
+-----------+
|         1 |
+-----------+
1 row in set (0.00 sec)
Thread1发布了一个新的插入:

insert into recent_leads (email, last_seen_at)
  values ('yes@example.com', '2019-12-12 18:23:35');
Thread2和Thread3将阻止尝试执行同一语句,直到Thread1提交或对其事务发出回滚。然后Thread2和Thread3竞争锁,同样的过程也会发生

因此,这是预期的效果,我们对此感到满意。当没有记录时,轮子就会脱落

Thread1、Thread2和Thread3都发出与上述相同的SQL。MySQL现在会立即将其返回给所有三个线程,而以前只有一个线程会继续:

+-----------+
| count(id) |
+-----------+
|         0 |
+-----------+
1 row in set (0.00 sec)
所有三个线程现在都尝试插入。其中两个将出现错误:

ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction
有没有一种方法可以让MySQL一直像第一个场景那样运行?我们希望Thread2和Thread3在理想情况下阻塞

谢谢,,
-乔纳森

所以我们最终放弃了锁定。相反,我们在一个单独的事务中提交该行,然后选择back all rows for a email减去
last\u insert\u id()
。如果我们发现一行主键较低,则假定另一个线程已经在处理该请求。这很好,因为它是无锁的,更容易调试