2016-06-08 125 views
1

自从最近2个月以来,我一直在使用nodejs,这是我在处理异步模块时遇到的问题。有时候,在某些错误异步错误异步从这个tasks.Consider代码的中间调用错误:如何使用异步模块在nodejs中实现回滚?

var mysql = require('mysql'); 
var async = require('async'); 

var connection = mysql.createConnection({ 
    host: 'localhost', 
    user: 'root', 
    database: 'test', 
    password: '12345' 
}); 

var chairArr = ['Red', 'Green', 'Yellow', 'Voilet', 'Brown']; 
var inventoryName = "Chairs"; 
addInventory(inventoryName, chairArr, function(err, result) { 
    if(err) { 
    console.log("Err : "+err); 
    } 
    console.log("Successfully added an inventory"); 
}); 


function addInventory(inventoryName, chairArr, callback) { 
    var sqlQuery = "INSERT INTO tb_inventory(name, added_on) VALUES(?, NOW())"; 
    connection.query(sqlQuery, [inventoryName], function(err, result) { 
    if(err) { 
     return callback(err, null); 
    } 
    var inventoryId = result.insertId; 
    var tasks = []; 
    for(var i = 0; i < chairArr.length; i++) { 
     tasks.push(addChair.bind(null, inventoryId, chairArr[i])); 
    } 
    async.parallel(tasks, function(taskErr, taskRes) { 
     if(taskErr) { 
     return callback(taskErr, null); 
     } 
     callback(null, result); 
    }); 
    }); 
} 

function addChair(inventoryId, chairColor, callback) { 
    var sqlQuery = "INSERT INTO tb_chairs(inventory_id, color) VALUES(?, ?)"; 
    connection.query(sqlQuery, [inventoryId, chairColor], function(err, result) { 
    if(err) { 
     return callback(err, null); 
    } 
    callback(null, result); 
    }); 
} 

这个简单的程序只是插入到两个表tb_inventory和tb_chairs。我的问题是:有时由于来自前端的参数或我的错误查询不会执行,而异步并行调用从该错误回调。有没有办法回滚(即删除表中的所有插入的条目)。谁能告诉我如何在错误回调中实现它(即跟踪所有的ID插入和删除?)。我们可以在全球使用mysql transactions吗?

+0

你读过[this](https://www.npmjs.com/package/mysql#transactions)吗? – robertklep

+0

是的,connection.beginTransaction需要一系列查询。但我不知道我将如何实现一系列函数调用之间的事务,这可能涉及或可能不涉及查询数据库。我想知道是否有某种方式来实现失败时的回滚机制。 –

回答

0

每当使用一系列函数时,我们都可以从池中获取本地连接,并在异步调用期间调用的函数中传递该本地连接。可以在异步调用的回调中处理提交或回滚。

var mysql = require('mysql'); 
var async = require('async'); 

var dbPool = mysql.createPool({ 
    host: 'localhost', 
    user: 'root', 
    database: 'test', 
    password: '12345', 
    connectionLimit: 10 
}); 

//var chairArr = ['Red', 'Green!++++++++++++++++!!!!!!!!!!!!!!!!!!!!!!!!!!!!', 'Yellow', 'Voilet', 'Brown']; //Case where query fails due to VARCHAR(20) limit 
var chairArr = ['Red', 'Green', 'Yellow', 'Voilet', 'Brown']; 
var inventoryName = "SOME ITEM "; 
dbPool.getConnection(function(conErr, localConnection) { 
    localConnection.beginTransaction(function(transactionErr) { 
     if(transactionErr) { 
      console.log("There was some error in begining transaction"); 
      return; 
     } 
     addInventory(localConnection, inventoryName, chairArr, function(err, result) { 
     if(err) { 
      console.log("Err : "+err); 
      return; 
     } 
     else { 
      console.log("Successfully added an inventory"); 
     } 
     }); 
    }); 
}); 


function addInventory(localConnection, inventoryName, chairArr, callback) { 
    var sqlQuery = "INSERT INTO tb_inventory(name, added_on) VALUES(?, NOW())"; 
    localConnection.query(sqlQuery, [inventoryName], function(err, result) { 
    if(err) { 
     return callback(err, null); 
    } 
    var inventoryId = result.insertId; 
    var tasks = []; 
    for(var i = 0; i < chairArr.length; i++) { 
     tasks.push(addChair.bind(null, localConnection, inventoryId, chairArr[i])); 
    } 
    async.parallel(tasks, function(err, asyncRes) { 
     if(err) { 
     rollback(localConnection, function(rollErr, rollRes) { 
      return callback(err, null); 
     }); 
     } 
     else { 
     localConnection.commit(function(commitErr, commitRes) { 
      console.log("transaction succeded"); 
      return callback(null, "Success"); 
     }); 
     } 
    }); 
    }); 
} 

function addChair(localConnection, inventoryId, chairColor, callback) { 
    var sqlQuery = "INSERT INTO tb_chairs(inventory_id, color) VALUES(?, ?)"; 
    localConnection.query(sqlQuery, [inventoryId, chairColor], function(err, result) { 
    if(err) { 
     return callback(err, null); 
    } 
    callback(null, result); 
    }); 
} 

function rollback(localConnection, callback) { 
    localConnection.rollback(function(err, result) { 
    if(err) { 
     console.log("ROLLBACK Failed"); 
     return callback(err, null); 
    } 
    console.log("ROLLBACK successful!"); 
    callback(null, result); 
    }); 
} 

我希望它有帮助。