使事务锁定一行以在 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 上读取的主要内容,如果未能解决你的问题,请参考以下文章

mariadb spider分片引擎初体验

数据库事务介绍

数据库 锁机制

Spring Data:如何锁定一个事务中的一行,让其他事务等到它被释放?

在SQLite上使用NHibernate时获取“Dababase被锁定”(没有事务的多进程)

事务的实现原理