【问题标题】:Making a transaction lock a row for reading on MariaDB使事务锁定一行以在 MariaDB 上读取
【发布时间】:2018-04-25 15:47:37
【问题描述】:

我在隔离级别方面遇到了一些问题,并且事务遇到了竞争条件问题。

我有一个带有状态字段的表,并且有 n 个进程访问它。每个事务应该返回status = 1的最旧行,并将状态更改为2。理论上,2个进程应该无法获得相同的注册表。但这并没有发生。由于该行未锁定以供事务读取。

您可以在下面找到交易的伪代码:

  1. 开始交易;
  2. 获取状态 = 1 的最旧行(按 date_created 排序);
  3. 更新行并设置status = 2;
  4. 提交事务;

竞争条件发生在 2 和 3 之间。因为该行没有为选择锁定。 MariaDB有可能吗?玩隔离级别?这样做的成本是多少?

【问题讨论】:

    标签: transactions mariadb isolation-level


    【解决方案1】:

    您可以在单个 UPDATE 语句中完成所有操作,例如

    更新表 SET field=value,.., status=2 WHERE 状态 = 1 ORDER BY date_created DESC 限制 1

    还有 SELECT FOR UPDATE,如果您需要做一些更有趣的事情。

    【讨论】:

    • 更新是不够的,因为我需要将行返回到我的代码。但是 SELECT FOR UPDATE 应该可以工作。谢谢
    【解决方案2】:

    这可能会加快查询速度以帮助避免锁定:

    INDEX(status, date_created) -- in this order.
    

    【讨论】:

      猜你喜欢
      • 2021-06-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-09
      • 1970-01-01
      相关资源
      最近更新 更多