使事务锁定一行以在 MariaDB 上读取

Making a transaction lock a row for reading on MariaDB

我在 ISOLATION 级别和事务 运行 中遇到了一些问题,进入了竞争条件问题。

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

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

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

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

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

 UPDATE table SET field=value,.., status=2
  WHERE status = 1
  ORDER BY date_created DESC
  LIMIT 1

还有 SELECT 更新,如果你需要做一些更有趣的事情。

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

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