gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-03 13:07:36 24 4
gpt4 key购买 nike

我遇到了一个看似简单的问题,结果却很难弄清楚。我们希望记录每次向我们展示营销(潜在客户)的时间,因此我们不会在 90 天内购买超过一次。许多潜在客户提供者可以多次向我们展示相同的潜在客户,通常是同时进行。我们希望将“接受”返回给一个主要供应商。

因此,让我们谈谈有效的场景:我们在过去 90 天内看到了 Material ,并在桌面上有了记录,并且有 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 理想地阻塞。

谢谢,
-乔纳森

最佳答案

所以我们最终放弃了锁定。相反,我们在单独的事务中提交该行,然后选择电子邮件的所有行减去 last_insert_id() .如果我们找到具有较低主键的行,我们假设另一个线程已经在处理该请求。这很好,因为它是无锁的,更容易调试。

关于MySQL:如何保持锁定并使其他线程等待尚未发生的插入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59310716/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com