分布式事务处理TransactionScope和非分布式事务处理
TransactionScope它的用途是为数据库访问提供了一个“轻量级”区别于:SqlTransaction的事物
TransactionScope这个事务自身还封装了多个数据库查询。只要任意一个SqlCommand对象引发异常,程序流控制就会跳出TransactionScope的using语句块,随后,TransactionScope将自行释放并回滚该事务。由于这段代码使用了using语句,所以SqlConnection对象和TransactionScope对象都将被自动调用Dispose()释放。由此可见,只需添加很少的几行代码,您就可以构建出一个事务模型,这个模型可以对异常进行处理,执行结束后会自行清理,此外,它还可以对命令的提交或回滚进行管理。
TransactionScope在文档中宣称只在“必要”情况下才提升事务级别(多数据库时才使用分布式事务,如果是同一个数据库,最好使用SqlTransaction),但是事实上不是这样。在TransactionScope内,只要你用不同的SqlConnection对象操作DB一次以上(不管你的目标是不是同一个实例、同一个库),都会提升事务级别到分布式事务。
1:确保参与事务的machine开启了分布式事务支持;
2:如果machine开启了防火墙,需要设置msdtc进程为例外;
3:参与事务的machine不能跨域(如果跨域,目前微软还没有确切的解决方案);
4:多数据库时才使用分布式事务,如果是同一个数据库,最好使用SqlTransaction.
大部分都是用SqlTransaction这个类来在程序代码中保证事务性,但是SqlTransaction是与SQLServer数据库相关的类,如果将这个类用在了B层,那么就突破了三层架构的底线了,如果将来换数据库(比如从SQLServer换到Oracle),D层和B层都得重写,所以这样做的局限性很大。
用TransactionScope,这个类是与具体数据库无关的类,用这个类来保证B层的事务性十分可行。
///<paramname="sendUserId"></param>
///<paramname="toUser">格式7FFA3AF2-E74B-4174-8403-5010C53E49A7|userName,7FFA3AF2-E74B-4174-8403-5010C53E49A7|userName</param>
///<paramname="content"></param>
///<paramname="sendedStatus">表示已送</param>
///<returns></returns>
publicstaticintsendMessage(stringsendUserId,stringtoUser,stringcontent,stringsendedStatus)
TransactionOptionstransactionOption=newTransactionOptions();
transactionOption.IsolationLevel=System.Transactions.IsolationLevel.ReadCommitted;
transactionOption.Timeout=newTimeSpan(0,0,60);
using(TransactionScopescope=newTransactionScope(TransactionScopeOption.Required,transactionOption))
insertMessage(sendUserId,toUser,content,sendedStatus);
receiveCount+=insertReceiveMessage(userids[0],sendUserId,content,"0");
thrownewException("发送信息异常,原因:"+ex.Message);
1、你把catch中的 trans.Rollback();去掉就可以了。因为前面已经trans.Commit();了,这个表示事物已经结束,后面再调用当然会出现前面的问题了。
2、另外不用指明trans.Rollback(),如果有异常的话,事物会自动回滚的。
3、楼上的,他事物是结束了,但是下面的插入语句并没有用到前面的事物,所以根本不需要再次打开事物的连接
本文来自投稿,不代表本站立场,如若转载,请注明出处:https://www.56xzw.com/showinfo-1-2955-0.html