Sequelize 事务(Transactions)全面指南
【免费下载链接】sequelize-docs-Zh-CN 项目地址: https://gitcode.com/gh_mirrors/se/sequelize-docs-Zh-CN
什么是数据库事务
数据库事务是指作为单个逻辑工作单元执行的一系列操作,要么完全执行,要么完全不执行。事务具有四个关键特性(ACID):
- 原子性(Atomicity):事务中的所有操作要么全部完成,要么全部不完成
- 一致性(Consistency):事务执行前后,数据库从一个一致状态变到另一个一致状态
- 隔离性(Isolation):多个事务并发执行时,一个事务的执行不应影响其他事务
- 持久性(Durability):事务一旦提交,其结果就是永久性的
Sequelize 中的事务类型
Sequelize 提供了两种使用事务的方式,各有适用场景:
1. 非托管事务(手动管理)
非托管事务需要开发者手动控制事务的提交(commit)和回滚(rollback)。这种方式提供了最大的灵活性,但也需要更多的代码管理。
// 开始事务
const t = await sequelize.transaction();
try {
// 执行数据库操作,传递事务对象
const user = await User.create({...}, { transaction: t });
// 更多操作...
// 手动提交事务
await t.commit();
} catch (error) {
// 出错时手动回滚
await t.rollback();
}
适用场景:
- 需要精细控制事务流程
- 事务中需要处理非数据库操作
- 复杂的事务逻辑
2. 托管事务(自动管理)
托管事务由 Sequelize 自动管理提交和回滚,开发者只需关注业务逻辑。
try {
const result = await sequelize.transaction(async (t) => {
// 在此回调中执行操作
const user = await User.create({...}, { transaction: t });
return user;
});
// 事务已自动提交
} catch (error) {
// 事务已自动回滚
}
优势:
- 代码更简洁
- 减少忘记提交/回滚的风险
- 错误处理更简单
高级事务特性
事务隔离级别
Sequelize 支持标准的事务隔离级别:
const { Transaction } = require('@sequelize/core');
// 可用的隔离级别
Transaction.ISOLATION_LEVELS.READ_UNCOMMITTED // 读未提交
Transaction.ISOLATION_LEVELS.READ_COMMITTED // 读已提交
Transaction.ISOLATION_LEVELS.REPEATABLE_READ // 可重复读
Transaction.ISOLATION_LEVELS.SERIALIZABLE // 串行化
设置隔离级别:
await sequelize.transaction({
isolationLevel: Transaction.ISOLATION_LEVELS.SERIALIZABLE
}, async (t) => {
// 事务代码
});
并发事务处理
Sequelize 支持嵌套事务和并发事务(除SQLite外):
sequelize.transaction((t1) => {
return sequelize.transaction((t2) => {
// 可以明确指定每个操作使用哪个事务
return Promise.all([
User.create({...}, { transaction: null }), // 不使用事务
User.create({...}, { transaction: t1 }), // 使用外层事务
User.create({...}) // 默认使用当前事务(t2)
]);
});
});
事务钩子(afterCommit)
可以在事务提交后执行特定操作:
await sequelize.transaction(async (t) => {
t.afterCommit(() => {
// 事务提交后执行的代码
// 适合发送通知、触发后续流程等
});
// 事务操作...
});
注意:如果事务回滚,afterCommit钩子不会执行。
最佳实践
- 生产环境必须使用事务:确保数据一致性
- 合理选择事务类型:
- 简单操作使用托管事务
- 复杂逻辑使用非托管事务
- 注意事务范围:不要在不必要的情况下使用长事务
- 处理死锁:准备好重试逻辑
- 结合模型钩子使用:如afterSave等
常见问题解决方案
问题1:如何在整个应用中自动传递事务?
解决方案:使用CLS(Continuation Local Storage):
const cls = require('cls-hooked');
const namespace = cls.createNamespace('my-app-namespace');
const { Sequelize } = require('@sequelize/core');
// 全局启用CLS
Sequelize.useCLS(namespace);
// 之后创建的所有实例都会自动支持CLS
const sequelize = new Sequelize(...);
启用后,事务会自动在回调链中传递,无需手动指定。
问题2:如何在事务中使用锁?
解决方案:
// 使用行锁
await User.findAll({
where: { id: 123 },
lock: true,
transaction: t
});
// 跳过已锁定的行
await User.findAll({
where: { status: 'active' },
lock: true,
skipLocked: true,
transaction: t
});
通过本指南,你应该已经掌握了Sequelize中事务的核心概念和使用方法。合理使用事务可以显著提高应用的可靠性和数据一致性。
【免费下载链接】sequelize-docs-Zh-CN 项目地址: https://gitcode.com/gh_mirrors/se/sequelize-docs-Zh-CN
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



