2016-06-08 97 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); 
    }); 
} 

我希望它有幫助。