【问题标题】:Node JS and node-firebird multiple queries in one transactionNode JS 和 node-firebird 一个事务中的多个查询
【发布时间】:2020-07-27 02:58:23
【问题描述】:

我现在试了两天,没有什么好结果。

transaction.query("INSERT INTO INVOICE (INVOICE_NO,INVOICE_NO_TMP,UNIT_TYPE,UNIT_TYPE_TEXT,TAX_PERCENT,QTY,SALE_PRICE,SERIALNUMBER,DISCOUNT,PARTNO,PARTNO_ID,DESCRIPTION) VALUES (?,?,?,?,?,?,?,?,?,?,?,?) RETURNING ID",array, function(err, result) {
      if (err){
        res.end(err.toString());
        transaction.rollback();
        db.detach();
        return result;                
      }
     })

当我做一个新的查询时,它只会启动一个新的事务,我不能回滚或提交。我只收到这条消息: 无效的事务句柄(期望显式事务开始)

如何在每次进行新查询时保留第一笔交易? db.transaction 似乎正在启动一个事务,但是在其中运行查询时它只会启动新的。

db.transaction(Firebird.ISOLATION_READ_COMMITED, await async  function(err,transaction) {
});

我想要这样:

transaction.query("INSERT INTO INVOICE (INVOICE_NO,INVOICE_NO_TMP,UNIT_TYPE,UNIT_TYPE_TEXT,TAX_PERCENT,QTY,SALE_PRICE,SERIALNUMBER,DISCOUNT,PARTNO,PARTNO_ID,DESCRIPTION) VALUES (?,?,?,?,?,?,?,?,?,?,?,?) RETURNING ID",array, function(err, result) {
  if (err){
    res.end(err.toString());
    transaction.rollback();
    db.detach();
    return result;                
  }
 })
transaction.query("INSERT INTO INVOICE (INVOICE_NO,INVOICE_NO_TMP,UNIT_TYPE,UNIT_TYPE_TEXT,TAX_PERCENT,QTY,SALE_PRICE,SERIALNUMBER,DISCOUNT,PARTNO,PARTNO_ID,DESCRIPTION) VALUES (?,?,?,?,?,?,?,?,?,?,?,?) RETURNING ID",array, function(err, result) {
  if (err){
    res.end(err.toString());
    transaction.rollback();
    db.detach();
    return result;                
  }
 })
 transaction.commit(function(err) {
   if (err)
     transaction.rollback();
   else
     db.detach();
 });

同一个交易。 我试了试,但没有成功。 我看到对于 mySQL 这很容易,但在 node-firebird 中却不是。 我查看了 github 中的测试索引,这有事务和多个插入,但这是完全错误的。这个测试没有展示如何在代码块之外使用相同的事务,所以它不是有用的信息。它不适用于遍历列表数组并进行插入。 我无法找到此信息仅适用于 node-firebird。 试图搜索示例,但它不存在。

【问题讨论】:

    标签: node.js node-modules


    【解决方案1】:

    我让它工作了。

    我使用承诺和等待。我在循环中使用它来遍历所有新的行项。 一个问题是奇怪的。 当插入 SQL 使用 RETURNING ID 时,每隔一行就会崩溃。我用了一整天的时间来解决这个问题。 SQL 中的 RETURNING 命令不适用于同一事务中的多个插入。但它在没有交易的情况下运作良好。 node-firebird 或 Firebird 引擎中的错误。 我不得不以另一种方式来做。我首先从导致新的最高行 id + 1 的过程中进行手动选择。然后我每次插入时只执行 rowID++。

    这是我的解决方案:

      var addItems= async function (i,params,ID){
        return new Promise((resolve, reject) => { // Important for waiting for the result
          var params2=[];
          params2.push(rowID);
          params2=params2.concat(params); 
            transaction.query("INSERT INTO INVOICE (ID, INVOICE_NO,INVOICE_NO_TMP,UNIT_TYPE,UNIT_TYPE_TEXT,TAX_PERCENT,QTY,SALE_PRICE,SERIALNUMBER,DISCOUNT,PARTNO,PARTNO_ID,DESCRIPTION) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?) ",params2,  function(err, result) {
                if (err){
                    transaction.rollback();
                    db.detach();
                    reject(err.toString());
                    return false;
                }
              resolve(true);    
            });
        });
      }
    

    我用这个在循环中调用它:

    var result=await addItems(i,params,invoice.head[0].INVOICE_NO_TMP)                      
      if (result==true){
        rowID++;
      }else{
        transaction.rollback();
        reject(result.toString());
        break;
        return false;
      }
    

    在循环之后我会这样做:

      transaction.commit(function(err) {
          if (err){
            reject(err.toString());
            transaction.rollback();
            db.detach();
            return false;
          }
        db.detach();
      });
    

    最后,我完成了:

    var result=await updateFromList();  
    res.end(result);
    

    updateFromList 函数是开始插入或更新所有行的函数。

    当我没有意识到 RETURNING ID 正在崩溃时,创建它并不容易。它需要进行大量测试才能实现,并意识到它正在崩溃。

    现在效果很好。 能够使用事务很重要,因为没有它,数据非常不稳定。

    【讨论】:

      猜你喜欢
      • 2021-03-05
      • 2016-05-08
      • 1970-01-01
      • 1970-01-01
      • 2021-12-19
      • 2023-03-16
      • 1970-01-01
      • 2014-01-29
      相关资源
      最近更新 更多