依赖模块:

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
}); function execTrans(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);
throw tErr;
});
} 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.");
}
})

仓促写给项目用,大神也可以帮我改进这个封装。

最新文章

  1. [转] nodemon 基本配置与使用
  2. CF733C Epidemic in Monstropolis[模拟 构造 贪心]
  3. CRM 2016 子表单中N:1关系 字段要求与新建时的关系
  4. 三角形问题的解决复杂度O(n^3)和O(nlogn)的比较
  5. 如何用按钮的click事件去触发a标签的click事件
  6. 用OOP设计以下场景。太阳发出太阳光,照射在墙壁上,在地面形成影子。
  7. HDU 4421 Bit Magic (图论-2SAT)
  8. 编译不通过:提示XXXX不是类或命名空间名 的解决办法
  9. web前端之 JS
  10. 通过yocto给p1010rdb定制linux,并启动linux
  11. 将类数组对象(array-like object)转化为数组对象(Array object)
  12. Google Adsense(Google网站联盟)广告申请指南
  13. URAL 1297 最长回文子串(后缀数组)
  14. C++中模板的特化与偏特化
  15. PL/SQL Dev连接Oracle弹出空白提示框的解决方法分享
  16. day2(基础数据类型)
  17. (转载)跟我一起学习VIM - The Life Changing Editor
  18. table 如何给tr border颜色
  19. Codeforces183D T-shirt
  20. Leetcode中单链表题总结

热门文章

  1. 剑指offer—第二章算法之二分查找(旋转数组的最小值)
  2. RabbitMQ链接不上异常
  3. 线程----BlockingQueue (转)
  4. aspose.word 在书签处插入符号
  5. 阻塞、非阻塞的概念和select函数的阻塞功能
  6. Java读写大文本文件(2GB以上)
  7. Go 语言做的几个验证码
  8. TestNG中同一个类中执行多个test()方法如何配置testng.xml
  9. [转]Linux中文件权限目录权限的意义及权限对文件目录的意义
  10. 干掉cmd:windows下使用linux命令行