使事务锁定一行以在 MariaDB 上读取
Posted
技术标签:
【中文标题】使事务锁定一行以在 MariaDB 上读取【英文标题】:Making a transaction lock a row for reading on MariaDB 【发布时间】:2018-04-25 15:47:37 【问题描述】:我在隔离级别方面遇到了一些问题,并且事务遇到了竞争条件问题。
我有一个带有状态字段的表,并且有 n 个进程访问它。每个事务应该返回status = 1的最旧行,并将状态更改为2。理论上,2个进程应该无法获得相同的注册表。但这并没有发生。由于该行未锁定以供事务读取。
您可以在下面找到交易的伪代码:
-
开始交易;
获取状态 = 1 的最旧行(按 date_created 排序);
更新行并设置status = 2;
提交事务;
竞争条件发生在 2 和 3 之间。因为该行没有为选择锁定。 MariaDB有可能吗?玩隔离级别?这样做的成本是多少?
【问题讨论】:
【参考方案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.
【讨论】:
以上是关于使事务锁定一行以在 MariaDB 上读取的主要内容,如果未能解决你的问题,请参考以下文章
Spring Data:如何锁定一个事务中的一行,让其他事务等到它被释放?