I'm building a simple webapp using NodeJS/Postgres that needs to make 3 insertions on database.
我正在使用NodeJS/Postgres构建一个简单的web应用程序,需要在数据库上进行3次插入。
To control the chain of statements I'm using pg-transaction.
为了控制语句链,我使用了pg-transaction。
My problem is that I have to always run the 2 first INSERTS, but I have a condition to run the 3rd one.
我的问题是,我必须总是运行2个第一个插入,但是我有一个条件来运行第3个。
Maybe my code could be build in a better manner (suggestions are welcome).
也许我的代码可以以更好的方式构建(欢迎建议)。
Here's a pseudo code:
这里有一个伪代码:
function(req, res) {
var tx = new Transaction(client);
tx.on('error', die);
tx.begin();
tx.query('INSERT_1 VALUES(...) RETURNING id', paramValues, function(err, result) {
if (err) {
tx.rollback();
res.send("Something was wrong!");
return;
}
var paramValues2 = result.rows[0].id;
tx.query('INSERT_2 VALUES(...)', paramValues2, function(err2, result2) {
if (err) {
tx.rollback();
res.send("Something was wrong!");
return;
}
// HERE'S THE PROBLEM (I don't want to run it always this last statement)
// If I don't run it, I will miss tx.commit()
if (req.body.value != null) {
tx.query('INSERT_3 VALUES(...)', paramValues3, function(err3, result3) {
if (err) {
tx.rollback();
res.send("Something was wrong!");
return;
}
tx.commit();
res.send("Everything fine!");
});
}
});
});
}
It seems so ugly to repeat three times the same if (err) {} after each query.
在每个查询之后重复三次相同的if (err){}似乎是如此的丑陋。
Trying to check some options I found Sequelize, but couldn't see a way to solve this problem with it.
我试着检查一些选项,找到了Sequelize,但是找不到解决这个问题的方法。
Any suggestions are welcome!
欢迎任何建议!
Thanks!
谢谢!
1 个解决方案
#1
3
Manual transaction management is a treacherous path, try to steer away from that! ;)
手工交易管理是一条危险的道路,试着远离它!,)
Here's how to do it properly, with the help of pg-promise:
以下是如何在pg-promise的帮助下正确地做到这一点:
function(req, res) {
db.tx(t => { // automatic BEGIN
return t.one('INSERT_1 VALUES(...) RETURNING id', paramValues)
.then(data => {
var q = t.none('INSERT_2 VALUES(...)', data.id);
if (req.body.value != null) {
return q.then(()=> t.none('INSERT_3 VALUES(...)', data.id));
}
return q;
});
})
.then(data => {
res.send("Everything's fine!"); // automatic COMMIT was executed
})
.catch(error => {
res.send("Something is wrong!"); // automatic ROLLBACK was executed
});
}
Or, if you prefer ES6 generators:
或者,如果你喜欢ES6发电机:
function (req, res) {
db.tx(function * (t) { // automatic BEGIN
let data = yield t.one('INSERT_1 VALUES(...) RETURNING id', paramValues);
let q = yield t.none('INSERT_2 VALUES(...)', data.id);
if (req.body.value != null) {
return yield t.none('INSERT_3 VALUES(...)', data.id);
}
return q;
})
.then(data => {
res.send("Everything's fine!"); // automatic COMMIT was executed
})
.catch(error => {
res.send("Something is wrong!"); // automatic ROLLBACK was executed
});
}
#1
3
Manual transaction management is a treacherous path, try to steer away from that! ;)
手工交易管理是一条危险的道路,试着远离它!,)
Here's how to do it properly, with the help of pg-promise:
以下是如何在pg-promise的帮助下正确地做到这一点:
function(req, res) {
db.tx(t => { // automatic BEGIN
return t.one('INSERT_1 VALUES(...) RETURNING id', paramValues)
.then(data => {
var q = t.none('INSERT_2 VALUES(...)', data.id);
if (req.body.value != null) {
return q.then(()=> t.none('INSERT_3 VALUES(...)', data.id));
}
return q;
});
})
.then(data => {
res.send("Everything's fine!"); // automatic COMMIT was executed
})
.catch(error => {
res.send("Something is wrong!"); // automatic ROLLBACK was executed
});
}
Or, if you prefer ES6 generators:
或者,如果你喜欢ES6发电机:
function (req, res) {
db.tx(function * (t) { // automatic BEGIN
let data = yield t.one('INSERT_1 VALUES(...) RETURNING id', paramValues);
let q = yield t.none('INSERT_2 VALUES(...)', data.id);
if (req.body.value != null) {
return yield t.none('INSERT_3 VALUES(...)', data.id);
}
return q;
})
.then(data => {
res.send("Everything's fine!"); // automatic COMMIT was executed
})
.catch(error => {
res.send("Something is wrong!"); // automatic ROLLBACK was executed
});
}