节点 MySQL:具有不同查询的事务

Node MySQL: Transaction with Varying Queries

问题

我正在尝试为我的 node.js 应用程序开发一个简单的框架,它允许我根据上下文和我需要完成的任务来传递要触发的各种查询的可变序列。

困难在于,当涉及到 insert/update/delete 语句时,就好像模块无法提交事务,而数据库仍然不受影响——这在单个查询和查询中都会发生在交易中,这对于交易来说尤其奇怪(我在最后调用 conn.commit())。

准系统代码

差异:有一个结果解析脚本也可以动态提供,以防需要根据插入的行进行特殊处理。

function runTransaction(queries)
{
    var tranResults = {};
    var tranDef = Promise.defer();
    connection.beginTransaction(function(err){
        if(err instanceof Error)
        {
            tranDef.reject(err);
            connection.rollback();
            return;
        }
        let index = -1;
        function runTransactionQueries()
        {
            if(index >= queries.length)
            {
                connection.commit();
                tranDef.resolve(tranResults);
                return;
            }
            index++;
            let query = queries[index];
            connection.query(query, function(err, result){
                if(err instanceof Error)
                {
                    tranDef.reject(err);
                    connection.rollback();
                    return;
                }
                tranResults[index] = result;
                return runTransactionQueries();
            })
        }
        return runTransactionQueries();
    }
    return tranDef.promise;
}
runTransaction([array,of,validated,query,objects]).then(results => {
    // This is always triggered, and it's always an OkPacket
    // But when I check the database after UPDATE, INSERT, or DELETE, the
    // queries have had no effect.
    console.log(results);
}).catch(e => {
    // This never fires.
    console.log(e);
})

我尝试过的事情

我试过使用承诺延期的动态数组来控制交易流,我试过让它们 运行 同步。我与数据库的所有连接都很好,当我对单个 GET 请求使用相同的连接或连接池时,它可以正常工作。我开始使用事务处理,因为使用 INSERT、UPDATE 或 DELETE 语句的 运行ning connection.query() 未能成功写入数据库,这让我觉得我可能不得不强制提交(尽管事实上,相同的查询来自 MySQL Workbench).

同样的问题出现在单个连接和连接池中:查询 returns 一个显示行已被更改和插入的 OkPacket,但是当我在 MySQL 中访问数据库时 Workbench,他们不在那里。

我的问题

我是不是漏掉了什么?我对 JavaScript 的了解表明这应该有效。这是我应该尝试的事情吗?是否有任何库或框架可以使在 node.js 中使用 MySQL 更简单?我正在使用的应用程序非常复杂,但我应该只手写我的交易吗?

嗯。我觉得不好意思。

答案是代码没有问题,但数据库有问题。在 MySQL workbench 中,在之前的调试工作中,我取消了查询 > 自动提交事务,这导致事务和语句在第一个应用于给定行后仍未提交 (感谢 InnoDB 提供特定于行的锁)。

虽然答案与代码无关,但在初始化数据库对象之后添加它可能会产生相同的效果:

pool.getConnection(function(err, conn){
  if(err instanceof Error){ throw err; }
  conn.query("SET AUTOCOMMIT=1", [], function(err){
    if(err instanceof Error){
      conn.release();
      throw err;
    }
    console.log("Auto-commit Transactions Enabled.");
    conn.release();
  });
});

我还在学习 MySQL 的工作原理。