我正在使用 NodeJS / Postgres 构建一个简单的Web应用程序,需要在数据库中进行3次插入。
为了控制语句链,我使用 pg-transaction 。
我的问题是我必须总是先运行第2个插件,但是我有条件要运行第3个插件。
也许可以以更好的方式构建我的代码(欢迎提出建议)。
这是一个伪代码:
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 always run 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!"); }); } }); }); }
在每个查询之后, 如果 重复三遍 if(err){} 看起来很丑。
尝试检查一些选项时,我发现了 Sequelize ,但是找不到解决此问题的方法。
欢迎任何建议!
谢谢!
手动交易管理是一条危险的道路,请设法避免这种情况!;)
这是在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 }); }
或者,如果您更喜欢ES7语法:
function (req, res) { db.tx(async t => { // automatic BEGIN let data = await t.one('INSERT_1 VALUES(...) RETURNING id', paramValues); let q = await t.none('INSERT_2 VALUES(...)', data.id); if (req.body.value != null) { return await 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 }); }
更新
在示例中,用ES7 async/ 替换了ES6生成器await,因为pg-promise停止了从9.0.0版本开始支持ES6生成器
async
await