nodejs连接sqlserver数据库支持事物封装-mssql模块

58 篇文章 16 订阅
57 篇文章 34 订阅

--安装模块

npm install async  --异步流程控制模块 ,async模块介绍:http://blog.csdn.net/zzwwjjdj1/article/details/51857959

--创建测试数据库和表

数据库 : nodetest,表 : test

--封装代码

dbTransaction.js:
/*
nodejs连接sqlserver数据库支持事物封装
2016年7月22日15:46:22
QQ : 452076103 意外金喜
 */
var dbTransaction = {};
var sql = require('mssql');
var config = {
  user: 'sa',
  password: '123456',
  server: '10.81.36.167', 
  database: 'nodetest',
  port:1433,
  options: {
    encrypt: true // Use this if you're on Windows Azure
  },
  pool: {
    min: 0,
    max: 10,
    idleTimeoutMillis: 3000
  }
};

dbTransaction.getTransaction = function(callback){

  var connection = new sql.Connection(config, function (err) {

    var transaction = new sql.Transaction(connection);
    
    callback(sql, transaction);
  })
};

module.exports = dbTransaction;

--测试-sql语句错误

错误位置:

age是int类型的,故意写成string

testTransaction.js
/*
测试连接sqlserver的事物机制
2016年7月22日15:51:52
 */
var async  = require('async');
var dbTransaction = require('./dbTransaction.js');

dbTransaction.getTransaction(function(sql, transaction){
	//开启事物
	transaction.begin(function(err) {

		if (err) {
			console.log(err);
			return;
		}
		//定义一个变量,如果自动回滚,则监听回滚事件并修改为true,无须手动回滚
    var rolledBack = false;

    //监听回滚事件
    transaction.on('rollback', function(aborted) {
    	console.log('监听回滚');
	    console.log('aborted值 :', aborted);
	    rolledBack = true;
    });

    //监听提交事件
    transaction.on('commit', function() {
    	console.log('监听提交');
	    rolledBack = true;
    });

    var request = new sql.Request(transaction);
    var task1 = function(callback){
  		request.query("insert into test (name, age) values ('a1', 20)", function(err, result) {
  			if (err) {
  				console.log(err);
  				callback(err, null);
  				return;
  			}
  			console.log('第一条语句成功');
  			callback(null, result)
  		})

  	};
  	var task2 = function(callback){
  		request.query("insert into test (name, age) values ('a2', 22)", function(err, result) {
  			if (err) {
  				console.log(err);
  				callback(err, null);
  				return;
  			}
  			console.log('第二条语句成功');
  			callback(null, result)
  		})

  	};
  	var task3 = function(callback){
  		request.query("insert into test (name, age) values ('a3', 'a')", function(err, result) {
  			if (err) {
  				console.log(err);
  				callback(err, null);
  				return;
  			}
  			console.log('第三条语句成功');
  			callback(null, result)
  		})

  	}
    async.series([task1, task2, task3],function(err,result){
    	var err = "11";
			if (err) {
				console.log('出现错误,执行回滚');
				if (!rolledBack) {

					//如果sql语句错误会自动回滚,如果程序错误手动执行回滚,不然事物会一致挂起.
	        transaction.rollback(function(err) {
	        	if (err) {

	          console.log('rollback err :',err);
	          return;
	        	}
	        	console.log('回滚成功');
	        });
			  }
			} else {
				console.log('无错误,执行提交');
				//执行提交
				transaction.commit(function(err) {
					if (err) {

	        console.log('commit err :',err);
	        return;
					}
					console.log('提交成功');
	      });
			}
    })
	});
})
这个测试就是向test表插入3条数据,按照预期,如果这个过程出现任何错误,3条数据都不会插入成功.
看看是不是这样的
执行结果:


数据库

总结:sql错误,并没有触发我们写的回滚事件,但程序监听到了回滚事件,数据库插入失败,这是因为mssql模块自己写了回滚.

--测试-非sql语句错误

也就是程序错误
错误位置:


testTransaction.js
/*
测试连接sqlserver的事物机制
2016年7月22日15:51:52
 */
var async  = require('async');
var dbTransaction = require('./dbTransaction.js');

dbTransaction.getTransaction(function(sql, transaction){
	//开启事物
	transaction.begin(function(err) {

		if (err) {
			console.log(err);
			return;
		}
		//定义一个变量,如果自动回滚,则监听回滚事件并修改为true,无须手动回滚
    var rolledBack = false;

    //监听回滚事件
    transaction.on('rollback', function(aborted) {
    	console.log('监听回滚');
	    console.log('aborted值 :', aborted);
	    rolledBack = true;
    });

    //监听提交事件
    transaction.on('commit', function() {
    	console.log('监听提交');
	    rolledBack = true;
    });

    var request = new sql.Request(transaction);
    var task1 = function(callback){
  		request.query("insert into test (name, age) values ('a1', 20)", function(err, result) {
  			if (err) {
  				console.log(err);
  				callback(err, null);
  				return;
  			}
  			console.log('第一条语句成功');
  			callback(null, result)
  		})

  	};
  	var task2 = function(callback){
  		request.query("insert into test (name, age) values ('a2', 22)", function(err, result) {
  			if (err) {
  				console.log(err);
  				callback(err, null);
  				return;
  			}
  			console.log('第二条语句成功');
  			callback(null, result)
  		})

  	};
  	var task3 = function(callback){
  		request.query("insert into test (name, age) values ('a3', 24)", function(err, result) {
  			if (err) {
  				console.log(err);
  				callback(err, null);
  				return;
  			}
  			console.log('第三条语句成功');
  			callback(null, result)
  		})

  	}
    async.series([task1, task2, task3],function(err,result){
    	var err = "11";
			if (err) {
				console.log('出现错误,执行回滚');
				if (!rolledBack) {

					//如果sql语句错误会自动回滚,如果程序错误手动执行回滚,不然事物会一致挂起.
	        transaction.rollback(function(err) {
	        	if (err) {

	          console.log('rollback err :',err);
	          return;
	        	}
	        	console.log('回滚成功');
	        });
			  }
			} else {
				console.log('无错误,执行提交');
				//执行提交
				transaction.commit(function(err) {
					if (err) {

	        console.log('commit err :',err);
	        return;
					}
					console.log('提交成功');
	      });
			}
    })
	});
})

执行结果:

数据库也为空,就不截图了.
总结:非sql错误,也就是程序错误,执行了我们写的回滚事件,程序监听到了回滚事件,数据库插入失败

--测试-无错误

无错误的情况,当然是皆大欢喜,程序不报错,数据插入成功.
去掉我们添加的错误,执行

数据库:
微笑终于成功了.......

最后说下,从begin方法开始,所有的程序错误都要手动处理,如果发生错误,而又没处理到,是不会回滚的.
  • 4
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值