Nodejs – 带有循环的node-mysql事务

我的nodejs项目目前使用node-mysql 。

我有一个多级数据数组,我想要插入到多个表中。 交易是我想到的,以实现我的目标。 以下是我的代码的大纲:

const mysql = require("mysql") const pool = mysql.createPool({ // connectionLimit=10 by default connectionLimit: 5, // 10 by default host: 'somehost', user: 'userblah', password: 'passworblah', database: 'dbblah' }) pool.getConnection(function(err, dbConnection) { dbConnection.beginTransaction(function(err1) { if (err1) { console.log(“Unable to begin the transaction”) return } arrayElements.forEach(function(element) { var insert1 = mysql.format(“INSERT INTO table1(…) VALUES (…)”, […]) dbConnection.query(insert1, function(error1, result1) { if (error1) { return dbConnection.rollback(function() { console.log(“Insert failed”) }) } const lastID = result1.insertId // A: more loops coming here to insert sub-data to more tables with lastID // B: SHOULD I dbConnection.commit here??? }) }) } } 

我认为在B dbConnection.commitforEach正在进行)还为时过早? 我该怎么做,以确保一切都完成了,然后commit

你忽略了数据库调用基本上是IO调用。 他们需要时间来处理。 所以,当你在forEach中调用insert语句时,所有的调用都被打开,并且不会等待你的查询来回答。

 var async = require('async') const mysql = require("mysql") const pool = mysql.createPool({ // connectionLimit=10 by default connectionLimit: 5, // 10 by default host: 'somehost', user: 'userblah', password: 'passworblah', database: 'dbblah' }) pool.getConnection(function(err, dbConnection) { dbConnection.beginTransaction(function(err1) { if (err1) { console.log(“Unable to begin the transaction”) return } Async.eachSeries(arrayElements,function iteratorOverElems(element,callback) { var insert1 = mysql.format(“INSERT INTO table1(…) VALUES (…)”, […]) dbConnection.query(insert1, function(error1, result1) { if (error1) { return callback(err) }) } const lastID = result1.insertId moreInsertion(arguments, function (err,result){ if(err){ return callback(err) } // A: more loops coming here to insert sub-data to more tables with lastID //now return the iterator return callback(); }) }) },function finalCb(err){ if(err){ //rollback }else{ // commmit here when all the insertions have been successful } }); } } 

这不是确定的代码。 你需要处理它。 使用asynchronous库来pipe理forEach循环函数中的每个元素的asynchronous函数处理。

我认为你应该提交时,所有的查询成功,否则回滚。

async.eachSeries像每个元素的调用迭代器一样工作。 如果使用err参数调用callback函数,则其余元素将被忽略,并调用最终callback函数。 有关更多详细信息,请参阅async doc https://github.com/caolan/async#each