转自:/zzwwjjdj1/article/details/51995536
--安装模块
npm install mssql --连接数据库模块 ,基本封装看这里:/zzwwjjdj1/article/details/51911270 npm install async --异步流程控制模块 ,async模块介绍:/zzwwjjdj1/article/details/51857959--创建测试数据库和表
数据库 : nodetest,表 : test--封装代码
dbTransaction.js:[javascript]view plain copy /* nodejs连接sqlserver数据库支持事物封装 7月22日15:46:22 QQ:452076103意外金喜 */ vardbTransaction={}; varsql=require('mssql'); varconfig={ user:'sa', password:'123456', server:'10.81.36.167', database:'nodetest', port:1433, options:{ encrypt:true//Usethisifyou'reonWindowsAzure }, pool:{ min:0, max:10, idleTimeoutMillis:3000 } }; dbTransaction.getTransaction=function(callback){ varconnection=newsql.Connection(config,function(err){ vartransaction=newsql.Transaction(connection); callback(sql,transaction); }) }; module.exports=dbTransaction;
--测试-sql语句错误
错误位置:age是int类型的,故意写成string
testTransaction.js
[javascript]view plain copy /* 测试连接sqlserver的事物机制 7月22日15:51:52 */ varasync=require('async'); vardbTransaction=require('./dbTransaction.js'); dbTransaction.getTransaction(function(sql,transaction){ //开启事物 transaction.begin(function(err){ if(err){ console.log(err); return; } //定义一个变量,如果自动回滚,则监听回滚事件并修改为true,无须手动回滚 varrolledBack=false; //监听回滚事件 transaction.on('rollback',function(aborted){ console.log('监听回滚'); console.log('aborted值:',aborted); rolledBack=true; }); //监听提交事件 transaction.on('commit',function(){ console.log('监听提交'); rolledBack=true; }); varrequest=newsql.Request(transaction); vartask1=function(callback){ request.query("insertintotest(name,age)values('a1',20)",function(err,result){ if(err){ console.log(err); callback(err,null); return; } console.log('第一条语句成功'); callback(null,result) }) }; vartask2=function(callback){ request.query("insertintotest(name,age)values('a2',22)",function(err,result){ if(err){ console.log(err); callback(err,null); return; } console.log('第二条语句成功'); callback(null,result) }) }; vartask3=function(callback){ request.query("insertintotest(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){ varerr="11"; if(err){ console.log('出现错误,执行回滚'); if(!rolledBack){ //如果sql语句错误会自动回滚,如果程序错误手动执行回滚,不然事物会一致挂起. transaction.rollback(function(err){ if(err){ console.log('rollbackerr:',err); return; } console.log('回滚成功'); }); } }else{ console.log('无错误,执行提交'); //执行提交 mit(function(err){ if(err){ console.log('commiterr:',err); return; } console.log('提交成功'); }); } }) }); })这个测试就是向test表插入3条数据,按照预期,如果这个过程出现任何错误,3条数据都不会插入成功. 看看是不是这样的 执行结果:
数据库
总结:sql错误,并没有触发我们写的回滚事件,但程序监听到了回滚事件,数据库插入失败,这是因为mssql模块自己写了回滚.
--测试-非sql语句错误
也就是程序错误 错误位置:testTransaction.js[javascript]view plain copy /* 测试连接sqlserver的事物机制 7月22日15:51:52 */ varasync=require('async'); vardbTransaction=require('./dbTransaction.js'); dbTransaction.getTransaction(function(sql,transaction){ //开启事物 transaction.begin(function(err){ if(err){ console.log(err); return; } //定义一个变量,如果自动回滚,则监听回滚事件并修改为true,无须手动回滚 varrolledBack=false; //监听回滚事件 transaction.on('rollback',function(aborted){ console.log('监听回滚'); console.log('aborted值:',aborted); rolledBack=true; }); //监听提交事件 transaction.on('commit',function(){ console.log('监听提交'); rolledBack=true; }); varrequest=newsql.Request(transaction); vartask1=function(callback){ request.query("insertintotest(name,age)values('a1',20)",function(err,result){ if(err){ console.log(err); callback(err,null); return; } console.log('第一条语句成功'); callback(null,result) }) }; vartask2=function(callback){ request.query("insertintotest(name,age)values('a2',22)",function(err,result){ if(err){ console.log(err); callback(err,null); return; } console.log('第二条语句成功'); callback(null,result) }) }; vartask3=function(callback){ request.query("insertintotest(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){ varerr="11"; if(err){ console.log('出现错误,执行回滚'); if(!rolledBack){ //如果sql语句错误会自动回滚,如果程序错误手动执行回滚,不然事物会一致挂起. transaction.rollback(function(err){ if(err){ console.log('rollbackerr:',err); return; } console.log('回滚成功'); }); } }else{ console.log('无错误,执行提交'); //执行提交 mit(function(err){ if(err){ console.log('commiterr:',err); return; } console.log('提交成功'); }); } }) }); })
执行结果:
数据库也为空,就不截图了.总结:非sql错误,也就是程序错误,执行了我们写的回滚事件,程序监听到了回滚事件,数据库插入失败
--测试-无错误
无错误的情况,当然是皆大欢喜,程序不报错,数据插入成功. 去掉我们添加的错误,执行数据库: 终于成功了.......
最后说下,从begin方法开始,所有的程序错误都要手动处理,如果发生错误,而又没处理到,是不会回滚的.