【问题标题】:"SQLITE_ERROR: cannot start a transaction within a transaction" with BEGIN ... COMMIT transaction control“SQLITE_ERROR:无法在事务中启动事务”与 BEGIN ... COMMIT 事务控制
【发布时间】:2015-04-29 08:23:54
【问题描述】:

我已经得到了上面提到的:在我的数据库初始化过程“SQLITE_ERROR无法启动事务中的交易”的错误,但没有发现存在对最佳实践的一些建议:herehere

所以,我调整我的代码添加db.run(“BEGIN”)和db.run(“凯明”)书挡,希望能够解决这个问题,但错误依然存在。 P>

我的代码如下所示:

我所说的各种初始化功能:

intializeMyTable1(...);
intializeMyTable2(...);
...
intializeMyTableN(...);

每个intialize功能大致相同:

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”) - 相同的错误 P>

我所做的发现是,如果我在一个时间只运行的初始化功能之一,我不明白的错误,但如果我链中的初始化功能,运行他们一前一后,我得到的错误。

任何想法/建议理解! P>

EDITS:次要错字修复 P>

【问题讨论】:

  • 我不知道的NodeJS。可是你的函数执行db.run("BEGIN") 每caling。把db.run("BEGIN")作为运行只能用时间。还db.run("COMMIT")在循环的结束。跨度>
  • 尝试db.run("BEGIN TRANSACTION")也跨度>
  • 谢谢,但我已经尝试db.run( “BEGIN TRANSACTION”)。此外,每次只调用的函数“开始”和“提交”一次 - 他们是书的目的。不过,或许是由于节点/ JS的异步特性,也许他们是重叠的。让我来看看这个。 SPAN>

标签: node.js sqlite


【解决方案1】:

除非您在帖子中省略了对 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*");

或任何其他随机顺序。这解释了您的错误消息“无法在事务中启动事务”。

看看https://github.com/mapbox/node-sqlite3/wiki/Control-Flow

【讨论】:

    【解决方案2】:

    好的,对代码做了一些小改动,现在可以使用了!

    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");
      }
    });
    ...
    }
    

    希望对遇到类似问题的人有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-10-04
      • 1970-01-01
      • 2017-09-14
      • 2018-03-30
      • 2017-01-31
      • 2021-01-18
      • 1970-01-01
      • 2011-05-26
      相关资源
      最近更新 更多