依赖模块:
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.");
}
})
仓促写给项目用,大神也可以帮我改进这个封装。