依賴模塊:
1. mysql:https://github.com/felixge/node-mysql
npm install mysql --save
2. async:https://github.com/caolan/async
npm install async --save
(ps: async模塊可換成其它Promise模塊如bluebird、q等)
因為Node.js的mysql模塊本身對于事務的封裝過于簡單,而且直接使用會有很嚴重callback hell,故我們封裝了兩個方法,一個用來初始化sql & params,一個用來執行事務。
初始化sql & params:
function_getNewSqlParamEntity(sql, params, callback) {if(callback) {return callback(null, {
sql: sql,
params: params
});
}return{
sql: sql,
params: params
};
}
如果你要執行多條sql語句,則需要:
var sqlParamsEntity =[];var sql1 = "insert table set a=?, b=? where 1=1";var param1 = {a:1, b:2};
sqlParamsEntity.push(_getNewSqlParamEntity(sql1, param1));var sql2 = "update ...";
sqlParamsEntity.push(_getNewSqlParamEntity(sql1, []));//...更多要事務執行的sql
然后我在我自己的dbHelper.js里封裝了execTrans的函數,用來執行事務
var mysql = require('mysql');var async = require("async");
module.exports={
execTrans: execTrans,
}var pool =mysql.createPool({
host:"mysql host",
user:"mysql login user",
password:"mysql login pwd",
database:"target db name",
connectionLimit:10,
port:"mysql db port",
waitForConnections:false});functionexecTrans(sqlparamsEntities, callback) {
pool.getConnection(function(err, connection) {if(err) {return callback(err, null);
}
connection.beginTransaction(function(err) {if(err) {return callback(err, null);
}
console.log("開始執行transaction,共執行" + sqlparamsEntities.length + "條數據");var funcAry =[];
sqlparamsEntities.forEach(function(sql_param) {var temp = function(cb) {var sql =sql_param.sql;var param =sql_param.params;
connection.query(sql, param,function(tErr, rows, fields) {if(tErr) {
connection.rollback(function() {
console.log("事務失敗," + sql_param + ",ERROR:" +tErr);throwtErr;
});
}else{return cb(null, 'ok');
}
})
};
funcAry.push(temp);
});
async.series(funcAry,function(err, result) {
console.log("transaction error: " +err);if(err) {
connection.rollback(function(err) {
console.log("transaction error: " +err);
connection.release();return callback(err, null);
});
}else{
connection.commit(function(err, info) {
console.log("transaction info: " +JSON.stringify(info));if(err) {
console.log("執行事務失敗," +err);
connection.rollback(function(err) {
console.log("transaction error: " +err);
connection.release();return callback(err, null);
});
}else{
connection.release();return callback(null, info);
}
})
}
})
});
});
}
這樣就可以執行事務了:
execTrans(sqlParamsEntity, function(err, info){if(err){
console.error("事務執行失敗");
}else{
console.log("done.");
}
})
倉促寫給項目用,大神也可以幫我改進這個封裝。