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

Sequelize事务回滚失效求助:已调用回滚但数据未回滚

Sequelize事务回滚不生效,numberseqs表更新未回滚

问题现象

使用Sequelize作为MySQL数据库的ORM框架,代码中已触发事务回滚操作,但numberseqs表的lastGenerated值仍持续递增,未按预期回滚。即使确认catch分支已执行,问题依旧存在,尝试设置事务隔离级别也无法解决。

原代码

async create(req, res) {
    const t = await SEQUELIZE.transaction()
    let lastGenerated = 0
    try
    {
        const numberSeqData = await numberSeq.findOne({ where: { document: 'project' } }, { transaction: t})
        if (numberSeqData)
        {
            lastGenerated = numberSeqData.lastGenerated + 1
            await numberSeq.update({ lastGenerated }, { where: { document: 'project' }},
            { transaction: t}
            )
        }
        else
        {
            throw new Error('NumberSeq not found')
        }
        const projectNew = await project.create({ 
            ProjectNumber : `PRJ-${lastGenerated}`,
            Name: req.body.name,
            Stage: req.body.stage,
            StartDate: req.body.startDate,
            EndDate: req.body.endDate,
            Description: req.body.description,
            IsActive: req.body.isActive,
        },{ transaction: t})
        await t.commit()
        res.status(200).send(projectNew)
    }
    catch(err)
    {
        await t.rollback()
        res.status(400).send(err)
    }
}

问题根源

两处参数传递不符合Sequelize API规范,导致数据库操作未正确绑定到事务中:

  • findOne参数错误:Model.findOne仅接受一个配置对象参数,事务配置需与where放在同一对象内,而非作为第二个独立参数。
  • update参数错误:Model.update仅接受两个参数,where条件与事务配置需合并到同一个配置对象中,不能拆分为两个独立参数。

未绑定事务的操作会直接提交到数据库,不受事务回滚控制,这就是lastGenerated值无法回滚的核心原因。

修正后的代码

async create(req, res) {
    const t = await SEQUELIZE.transaction()
    let lastGenerated = 0
    try {
        // 将transaction合并到findOne的配置对象中
        const numberSeqData = await numberSeq.findOne({ 
            where: { document: 'project' },
            transaction: t
        })
        if (numberSeqData) {
            lastGenerated = numberSeqData.lastGenerated + 1
            // 将where与transaction合并到update的同一个配置对象中
            await numberSeq.update(
                { lastGenerated }, 
                { 
                    where: { document: 'project' },
                    transaction: t
                }
            )
        } else {
            throw new Error('NumberSeq not found')
        }
        const projectNew = await project.create({ 
            ProjectNumber : `PRJ-${lastGenerated}`,
            Name: req.body.name,
            Stage: req.body.stage,
            StartDate: req.body.startDate,
            EndDate: req.body.endDate,
            Description: req.body.description,
            IsActive: req.body.isActive,
        },{ transaction: t})
        await t.commit()
        res.status(200).send(projectNew)
    } catch(err) {
        await t.rollback()
        res.status(400).send(err)
    }
}

关键注意事项

  • 所有需要纳入事务控制的数据库操作(查询、更新、插入等),都必须在配置参数中明确传入transaction: t。
  • 严格遵循Sequelize的API参数格式,避免因参数拆分导致事务绑定失效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 17:11:10