事务的两种实现方法
托管托管(auto-callback):一个将根据 promise 链的结果自动提交或回滚事务,(如果启用)用回调将该事务传递给所有调用
- sequelize.transaction 来启动托管事务。 如果返回链中的所有 promise 都已成功解决,则事务被提交。 如果一个或几个 promise 被拒绝,事务将回滚。
return sequelize.transaction(function (t) {
return User.create({
firstName: 'Abraham',
lastName: 'Lincoln'
}, {transaction: t}).then(function (user) {
return user.setShooter({
firstName: 'John',
lastName: 'Boothe'
}, {transaction: t});
});
}).then(function (result) {
}).catch(function (err) {
});
- 抛出错误到回滚
使用托管事务时,你应该 永不 手动提交或回滚事务。 如果所有查询都成功,但您仍然希望回滚事务(例如因为验证失败),则应该抛出一个错误来断开和拒绝链接:
return sequelize.transaction(function (t) {
return User.create({
firstName: 'Abraham',
lastName: 'Lincoln'
}, {transaction: t}).then(function (user) {
throw new Error();
});
});
- 启用 CLS自动事物: 你不需要直接访问 namespace.get(‘transaction’),因为所有查询都将自动在命名空间中查找事务:
sequelize.transaction(function (t1) {
return User.create({ name: 'Alice' });
});
- 并行事物和部分设置事物:你可以在一系列查询中执行并发事务,或者将某些事务从任何事务中排除。 使用 {transaction: } 选项来控制查询所属的事务
sequelize.transaction(function (t1) {
return sequelize.transaction(function (t2) {
return Promise.all([
User.create({ name: 'Bob' }, { transaction: null }),
User.create({ name: 'Mallory' }, { transaction: t1 }),
User.create({ name: 'John' })
]);
});
});
Sequelize.Transaction.ISOLATION_LEVELS.READ_UNCOMMITTED // "READ UNCOMMITTED"
Sequelize.Transaction.ISOLATION_LEVELS.READ_COMMITTED // "READ COMMITTED"
Sequelize.Transaction.ISOLATION_LEVELS.REPEATABLE_READ // "REPEATABLE READ"
Sequelize.Transaction.ISOLATION_LEVELS.SERIALIZABLE // "SERIALIZABLE"
- 默认情况下,sequelize 使用数据库的隔离级别。 如果要使用不同的隔离级别,请传入所需级别作为第一个参数:
return sequelize.transaction({
isolationLevel: Sequelize.Transaction.ISOLATION_LEVELS.SERIALIZABLE
}, function (t) {
});
- 非托管事务(then-callback):非托管事务强制您手动回滚或提交交易。 如果不这样做,事务将挂起,直到超时。 要启动非托管事务,请调用 sequelize.transaction() 而不用 callback(你仍然可以传递一个选项对象),并在返回的 promise 上调用 then。 请注意,commit() 和 rollback() 返回一个 promise。
return sequelize.transaction().then(function (t) {
return User.create({
firstName: 'Homer',
lastName: 'Simpson'
}, {transaction: t}).then(function (user) {
return user.addSibling({
firstName: 'Lisa',
lastName: 'Simpson'
}, {transaction: t});
}).then(function () {
return t.commit();
}).catch(function (err) {
return t.rollback();
});
});