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
相关产品推荐
相关产品推荐

