我在数据库初始化过程中遇到了上述“SQLITE_ERROR:无法在事务中启动事务”错误,但确实发现有一些最佳实践建议:here和{{3 }}
所以,我调整了我的代码以添加db.run(“BEGIN”)和db.run(“COMMIT”)书挡以希望解决问题,但错误仍然存在。
以下是我的代码:
我调用各种初始化函数:
intializeMyTable1(...);
intializeMyTable2(...);
...
intializeMyTableN(...);
每个初始化函数大致相同:
initializeMyTable1: function(...){
...
db.run("BEGIN")
db.run("CREATE TABLE if not exists MyTable1 (...)", function (err) {
if (err !== null) {
logger.error("Database Error:" + err);
}
else {
for (var i = 0; i < SomeNumber; i++) {
db.run("INSERT INTO MyTable1 (...) VALUES (...)", function (err) {
if (err !== null) {
...
}
});
}
}
});
db.run("COMMIT");
...
}
我尝试过db.run(“END”)而不是db.run(“COMMIT”) - 同样的错误。
我所发现的是,如果我一次只运行一个初始化函数,我不会得到错误,但是如果我链接初始化函数,一个接一个地运行它们,我就会收到错误。
任何想法/建议都表示赞赏!
编辑:小错字修正
答案 0 :(得分:2)
除非您在帖子中忽略了对db.serialize()
的调用,否则您实际上并没有修复错误。
所有语句都是异步执行的,这意味着db.run
实际上并不运行语句,而是将其排入队列。如果没有明确地包含在db.serialize()
中,则排队的语句将并行执行。
因此,预计不会按照给定的顺序一个接一个地执行以下操作:
db.run("BEGIN");
db.run("*do sql stuff*");
db.run("COMMIT");
db.run("BEGIN");
db.run("*do sql stuff*");
db.run("COMMIT");
可能会以
执行db.run("BEGIN");
db.run("BEGIN");
db.run("COMMIT");
db.run("COMMIT");
db.run("*do sql stuff*");
db.run("*do sql stuff*");
或任何其他随机顺序。这解释了您的错误消息“无法在事务中启动事务”。
答案 1 :(得分:0)
好的,对代码做了一些小改动,现在就可以了!
initializeMyTable1: function(...){
...
// treat the CREATE as independent of my BEGIN ... COMMIT flow
db.exec("CREATE TABLE if not exists MyTable1 (...)", function (err) {
if (err !== null) {
logger.error("Database Error:" + err);
}
else {
// BEGIN ... COMMIT bookends only relate to INSERTs
db.run("BEGIN");
for (var i = 0; i < SomeNumber; i++) {
db.run("INSERT INTO MyTable1 (...) VALUES (...)", function (err) {
if (err !== null) {
...
}
});
}
db.run("COMMIT");
}
});
...
}
希望能帮助任何有类似问题的人。