You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Sequelize异步查询并发执行是否会读取到未更新旧值问题咨询

结论

会出现读取到旧值的情况,Sequelize本身不存在查询等待另一个更新操作完成的默认机制。


原因说明

  • Sequelize作为ORM层,仅负责将业务侧的查询、更新操作转换为SQL语句发送到数据库,本身没有全局的单行操作调度、排队逻辑。两个异步函数并发执行时,操作会独立发往数据库,很容易触发竞态条件:

函数A先查询拿到旧值 → 函数B在A的更新操作执行完成前也查询拿到相同旧值 → A先完成更新 → B基于旧值计算后执行更新,最终覆盖A的更新结果,导致数据异常。

  • 这类并发读写问题本质是数据库层面的事务隔离级别问题,Sequelize默认不会替业务做额外的并发控制。

常见解决方案

1. 悲观锁(适合冲突频率高的场景)

查询时主动加行锁,持有锁的事务完成前,其他同数据行的查询会等待锁释放,避免读到未提交的旧值,需要包裹在事务中使用,示例代码:

const t = await sequelize.transaction();
try {
  // lock: true 表示对查询到的行加排他锁
  const targetRow = await YourModel.findOne({
    where: { id: 目标行ID },
    lock: true,
    transaction: t
  });
  // 执行业务计算逻辑
  targetRow.目标列 = 计算后的新值;
  await targetRow.save({ transaction: t });
  await t.commit();
} catch (err) {
  await t.rollback();
  throw err;
}

2. 乐观锁(适合冲突频率低的场景)

给对应数据表加version字段,Sequelize定义模型时开启version: true配置,更新操作会自动校验版本号,若版本号不匹配(说明其他事务已经更新过当前行)会抛出错误,业务侧捕获错误后重试即可。


内容的提问来源于stack exchange,提问作者Viriato

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 20:30:01