使事务锁定一行以在 MariaDB 上读取
Making a transaction lock a row for reading on MariaDB
我在 ISOLATION 级别和事务 运行 中遇到了一些问题,进入了竞争条件问题。
我有一个带有状态字段的 table,并且有 n 个进程访问它。每个事务应该return status = 1 的oldest 行,并将status 更改为2。理论上,2 个进程应该无法获得相同的registry。但这并没有发生。由于该行未被锁定以供事务读取。
您可以在下面找到交易的伪代码:
- 开始交易;
- 获取状态 = 1 的最旧行(按 date_created 排序);
- 更新行并设置状态 = 2;
- 提交交易;
竞争条件发生在 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.
我在 ISOLATION 级别和事务 运行 中遇到了一些问题,进入了竞争条件问题。
我有一个带有状态字段的 table,并且有 n 个进程访问它。每个事务应该return status = 1 的oldest 行,并将status 更改为2。理论上,2 个进程应该无法获得相同的registry。但这并没有发生。由于该行未被锁定以供事务读取。
您可以在下面找到交易的伪代码:
- 开始交易;
- 获取状态 = 1 的最旧行(按 date_created 排序);
- 更新行并设置状态 = 2;
- 提交交易;
竞争条件发生在 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.