【问题标题】:How to handle MySQL locks?如何处理 MySQL 锁?
【发布时间】:2012-06-12 08:36:07
【问题描述】:

我的要求是,用户可以点击并使用该交易。 一个交易只能由一个成员使用,因此当用户尝试使用交易时我会锁定表并解锁它。因此,如果两个用户点击并试图利用该交易,它将形成一个队列,它将阻止两个用户利用该交易。

代码是这样的

LOCK TABLES deal WRITE;
//MySQL queries and my php code goes here.
UNLOCK TABLES;

现在的问题是,如果我的 php 代码在锁定和解锁之间出现问题怎么办? 桌子会永久锁定吗?无论如何我可以设置锁定表的最长时间吗?

【问题讨论】:

标签: php mysql database transactions phpmyadmin


【解决方案1】:

如果我在你的位置,我会创建一个名为locked_deals 的数据库表。它将有一个名为 deal_id 的列。当用户选择一个交易时,它的 deal_id 将被插入到locked_deals 表中。当下一个用户点击同一个交易时,它会首先检查 deal_id 是否在锁定表中。如果是,则不允许用户选择交易。最后,当一切正常时,我们可以在进程结束时从锁表中删除 lock_id。对于由于 php 代码中的任何异常而卡在表中的 lock_ids - 我们可以创建一个后台服务,每 n 分钟清除 lock_deals 表中卡住的 ids(在最后 n 分钟内一直卡住)。 希望对您有所帮助。

【讨论】:

  • 这不起作用:一个进程可以在另一个进程检查表但没有找到 lock_id 之后在表中添加 lock_id。在这种情况下,第二个进程也会将 lock_id 添加到表中。这里我们真的需要原生 MySQL 锁。
  • @Aurel 通过将 lock_id 作为主键,我们可以确保没有两个用户/进程可以将相同的 deal_id 添加到表中。在 lock_ids 表中添加/删除 deal_id 的整个过程将通过存储过程完成,并且可以轻松处理任何主键违规,从而确保只有 1 个用户/进程获得特定交易的锁定。
【解决方案2】:

如果客户端会话的连接终止,无论是正常还是异常,服务器都会隐式释放会话持有的所有表锁。

Source

【讨论】:

    猜你喜欢
    • 2013-12-03
    • 2011-11-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-23
    • 1970-01-01
    • 2011-12-27
    • 1970-01-01
    相关资源
    最近更新 更多