qiu*_*jie 52 transactions sequelize.js
Node.js 7及更高版本已经支持async/await语法.我应该如何使用sequelize事务的async/await?
小智 121
let transaction;
try {
// get transaction
transaction = await sequelize.transaction();
// step 1
await Model.destroy({where: {id}, transaction});
// step 2
await Model.create({}, {transaction});
// step 3
await Model.update({}, {where: {id}, transaction });
// commit
await transaction.commit();
} catch (err) {
// Rollback transaction only if the transaction object is defined
if (transaction) await transaction.rollback();
}
Run Code Online (Sandbox Code Playgroud)
kos*_*nix 37
接受的答案是"非托管交易",这需要调用commit和rollback明确.对于任何想要"托管交易"的人来说,这就是它的样子:
try {
// Result is whatever you returned inside the transaction
let result = await sequelize.transaction( async (t) => {
// step 1
await Model.destroy({where: {id: id}, transaction: t});
// step 2
return await Model.create({}, {transaction: t});
});
// In this case, an instance of Model
console.log(result);
} catch (err) {
// Rollback transaction if any errors were encountered
console.log(err);
}
Run Code Online (Sandbox Code Playgroud)
要回滚,只需在事务函数中抛出一个错误:
try {
// Result is whatever you returned inside the transaction
let result = await sequelize.transaction( async (t) => {
// step 1
await Model.destroy({where: {id:id}, transaction: t});
// Cause rollback
if( false ){
throw new Error('Rollback initiated');
}
// step 2
return await Model.create({}, {transaction: t});
});
// In this case, an instance of Model
console.log(result);
} catch (err) {
// Rollback transaction if any errors were encountered
console.log(err);
}
Run Code Online (Sandbox Code Playgroud)
如果任何在事务块内引发错误的代码,则会自动触发回滚.
user7403683给出的答案描述了用于非托管事务的异步/等待方式(http://docs.sequelizejs.com/manual/tutorial/transactions.html#unmanaged-transaction-then-callback-)
异步/等待样式的托管事务可能如下所示:
await sequelize.transaction( async t=>{
const user = User.create( { name: "Alex", pwd: "2dwe3dcd" }, { transaction: t} )
const group = Group.findOne( { name: "Admins", transaction: t} )
// etc.
})
Run Code Online (Sandbox Code Playgroud)
如果发生错误,事务将自动回滚。
如果启用了 CLS,Sequelize 可以使用它来保留您的事务对象并自动将其传递给continuation-passing循环内的所有查询。
设置:
import { Sequelize } from "sequelize";
import { createNamespace } from "cls-hooked"; // npm i cls-hooked
const cls = createNamespace("transaction-namespace"); // any string
Sequelize.useCLS(cls);
const sequelize = new Sequelize(...);
Run Code Online (Sandbox Code Playgroud)
用法:
const removeUser = async (id) => {
await sequelize.transaction(async () => { // no need `async (tx)`
await removeUserClasses(id);
await User.destroy({ where: { id } }); // will auto receive `tx`
});
}
const removeUserClasses = async (userId) => {
await UserClass.destroy({ where: { userId } }); // also receive the same transaction object as this function was called inside `sequelize.transaction()`
await somethingElse(); // all queries inside this function also receive `tx`
}
Run Code Online (Sandbox Code Playgroud)
这个怎么运作?
从 Sequelize 源代码: github.com/sequelize
if (useCLS && this.sequelize.constructor._cls) {
this.sequelize.constructor._cls.set('transaction', this);
}
Run Code Online (Sandbox Code Playgroud)
if (options.transaction === undefined && Sequelize._cls) {
options.transaction = Sequelize._cls.get('transaction');
}
Run Code Online (Sandbox Code Playgroud)
阅读更多:
| 归档时间: |
|
| 查看次数: |
38543 次 |
| 最近记录: |