【问题标题】:Is sqlite last_insert_rowid atomic?sqlite last_insert_rowid 是原子的吗?
【发布时间】:2024-01-19 20:38:01
【问题描述】:

我使用 node.js sqlite3 来操作数据。我使用这些代码将数据插入数据库并获取插入的 id:

db.run("INSERT INTO myTable (name) VALUES ('test')");
db.get("SELECT last_insert_rowid() as id", function (err, row) {
     console.log('Last inserted id is: ' + row['id']);
});

我认为这并不稳定。我的数据库连接始终打开。当我的服务器在来自客户端的多个同时连接上提供此代码时,SELECT last_insert_rowid() 是否正确获取 id? sqlite last_insert_rowid 是原子的吗? 谢谢。

【问题讨论】:

    标签: node.js sqlite concurrency


    【解决方案1】:

    last_insert_rowid() 返回此连接上最后一个插入操作的 ROWID。

    如果从同一数据库连接上的多个线程调用该函数,结果是不可预测的。

    文档(用于 C API): https://www.sqlite.org/c3ref/last_insert_rowid.html

    如果您不在多个线程之间共享数据库连接(会话)以进行并发插入,这是安全的。如果多个线程在同一个连接上插入,这是不安全的,即您可能会获得 ID 或完全无效的 ID。

    【讨论】:

    • 谢谢 sstn,在事务中使用该代码能解决问题吗?
    • @hahamed 相关文档没有提到类似的内容。问题是您是否在单个数据库连接上使用线程(node.js 本机不支持)进行并发插入。这是只有您或任何有权访问代码库的人才能说的话。
    • 我使用 node.js 来服务客户端。我不明白:并发插入是否意味着 node.js 的线程?
    • last_insert_rowid() 受交易保护。请注意,每个客户端都有自己的本地数据库。
    【解决方案2】:

    通过文档sqlite3 Database#run(sql, [param, ...], [callback]) 您可以从回调中检索lastID

    【讨论】:

      【解决方案3】:
      try{
      
          db.run("INSERT INTO TABLE_NAME VALUES (NULL,?,?,?,?)",data1,data2,data3,data4,function(err){
                          if(err){
                              callback({"status":false,"val":err});
                          }else{
                              console.log("val  "+this.lastID);
                              callback({"status":true,"val":""});
                          }
                      });
      }catch(ex){
          callback({"status":false,"val":ex});
      }
      

      this.lastID 返回最后插入的行 id By documentation sqlite3 Database#run(sql, [param, ...], [callback])

      【讨论】:

      • 在两个表中发生多次插入,第二个表的数据依赖于第一个表的情况怎么办
      【解决方案4】:

      This.data.lastID 会给你最后插入的 ID。

      【讨论】:

        【解决方案5】:

        对于 Node.js Sqlite3 最后插入的 id,你可以使用 lastId

        这是一个简单的例子

        db.run("INSERT INTO foo ...", function(err) {
            if(null == err){
                // row inserted successfully
                console.log(this.lastID);
            } else {
                //Oops something went wrong
                console.log(err);
            }
        });
        

        【讨论】:

          最近更新 更多