【发布时间】:2019-04-17 08:49:10
【问题描述】:
在node-sqlite3中,如果db当前处于序列化模式,下一条语句是在前一条语句的回调完成之前等待,还是回调与下一条语句同时运行?
使用node-sqlite3 编写事务的最佳方式是什么?我考虑过这两种方法,但我不确定哪一种是正确的,或者即使它们都是错误的。
// NEXT DB STATEMENT WAITS FOR CALLBACK TO COMPLETE?
db.serialize(() => {
db.run('BEGIN');
// statement 1
db.run(
sql1,
params1,
(err) => {
if (err) {
console.error(err);
return db.serialize(db.run('ROLLBACK'));
}
}
);
// statement 2
db.run(
sql2,
params2,
(err) => {
if (err) {
console.error(err);
return db.serialize(db.run('ROLLBACK'));
}
return db.serialize(db.run('COMMIT));
}
);
});
// NEXT DB STATEMENT DOES NOT WAIT FOR CALLBACK TO COMPLETE?
db.serialize(() => {
db.run('BEGIN');
// statement 1
db.run(
sql1,
params1,
(err) => {
if (err) {
console.error(err);
return db.serialize(db.run('ROLLBACK'));
}
db.serialize(() => {
// statement 2
db.run(
sql2,
params2,
(err) => {
if (err) {
console.error(err);
return db.serialize(db.run('ROLLBACK'));
}
return db.serialize(db.run('COMMIT));
}
);
});
}
);
});
【问题讨论】:
-
“下一条语句会在前一条语句的回调完成之前等待” - 请参阅文档。 github.com/mapbox/node-sqlite3/wiki/…
-
@Tomalak 我做了,但文档没有提到回调会发生什么。它只是说“请注意,不是直接在回调函数中安排的查询不一定是序列化的”,这并没有回答我原来的问题。
-
嗯,我明白了。我看起来这个确切的问题已经在node-sqlite3 issue #304 中讨论过了,但是这个帖子很旧而且没有定论。
-
我很好奇:您在使用我提出的解决方案吗?它是否按预期工作?
-
@Tomalak 虽然我并没有完全使用它,但它确实对我有很大帮助。我已经处于著名的回调地狱中,因此现在更改整个代码库以使用 Promise 将是太多了。因此,我在回答开始时遵循了您的建议:为每个新事务打开一个序列化模式的新数据库连接,并在完成后关闭,从而保证不会对同一连接对象发生其他写入。
标签: node.js node-sqlite3