在Sequelize for Postgres中使用事务 [英] Using Transaction in Sequelize for Postgres
问题描述
我正在尝试在noodejs中进行续集交易。我正在使用postgres作为数据库。当我调用testDel时,事务将自动提交到testDel中。即使事务自动提交已设置为false。
I am trying the transaction for sequelize in noodejs. I am using postgres as my database. When I call the testDel the transaction get autocommitted in the testDel. Even if transaction autocommit already set to false.
如果我将变量t从Db.transaction传递给testDel,则它将等待手动提交/回滚。
我可以不将t传递给函数吗?
If I pass the variable t from the Db.transaction to testDel, then it will wait for the manual commit / rollback. Can I do without passing t into function? It make coding very complicated.
编码如下:
Db.transaction({autocommit: false}).then((t) => {
args = {vcTitle: {$ilike: '%ulie%'}};
let boDelete = true;
testDelPost(t, args)
.then(rersult =>{
if(rersult){
t.commit();
}else{
t.rollback();
}
})
});
function testDel(args){
//the result got deleted and auto committed after this destroy, it
//doesn't wait for the above transaction to decide the commit or rollback.
//If I pass t, and set traction: t in the destroy, then it work as expected
return Db.models.Post.destroy({where: args})
.then(result =>{
if(result > 0){
return true;
}else{
return false;
}
})
.error(status =>{
return error;
})
}
推荐答案
使用继续本地存储。这会将全局级别的Sequelize包分配给一个命名空间,以便从其创建的所有实例在执行事务时都引用该命名空间。
Use Continuation Local Storage. This assigns the global-level Sequelize package to a "namespace", so that all instances created from it reference the namespace when performing transactions.
按如下方式初始化Sequelize(假设ES6导入语法):
You initialise Sequelize as follows (assuming ES6 import syntax):
// Grab packages we need
import Sequelize from 'sequelize';
import Cls from 'continuation-local-storage';
// Assign namespace to database
Sequelize.cls = Cls.createNamespace('db');
然后,您可以执行交易而无需显式传递 t
。它还回滚未捕获的异常(或技术上未解决的承诺),并提交已解决的承诺:
This then allows you to perform transactions without explicitly passing t
around. It also rolls back on uncaught exceptions (or technically, unresolved promises), and commits on resolved promises:
以下是我在生产代码中使用的示例函数,
The following is a sample function I'm using in production code that demonstrates the concept in action.
它...
- 开始交易(
BEGIN;
在PostgreSQL中) - 创建一个新帐户(
插入帐户 ...
) - 创建一个将帐户加入帐户类型的条目(
INSERT INTO account_type_accounts ...
) - 创建将用户链接到帐户的条目(
插入 users_accounts ...
) - 仅在以上所有条件均获得成功时执行插入(
COMMIT;
)。如果不是,它将回滚(ROLLBACK;
)
- Starts a transaction (
BEGIN;
in PostgreSQL) - Creates a new account (
INSERT INTO "accounts"...
) - Creates an entry that joins an account to an account type (
INSERT INTO "account_type_accounts"...
) - Creates an entry that links the user to an account (
INSERT INTO "users_accounts"...
) - Only performs the inserts if ALL of above succeeded (
COMMIT;
). If not, it rolls back (ROLLBACK;
)
以下是代码:
createAccount (user, accountType, query = {}) {
// Start transaction
return this.db.connection.transaction(() => {
// Create the new account
return this.db.models.Account.create(query).then(account => {
// Associate with user & account type
return P.all([user.addAccount(account), accountType.addAccount(account)]).then(()=> {
// Return account back up the promise chain
return account;
});
});
});
}
请注意,缺少 t
变量或显式回滚/提交。
Note the lack of t
variables or explicit rollback/commit.
这篇关于在Sequelize for Postgres中使用事务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!