一、什么是TransactionScope?

  TransactionScope即范围事务(类似数据库中的事务),保证事务声明范围内的一切数据修改操作状态一致性,要么全部成功,要么全部失败回滚.

  MSDN:如果在事务范围内未不发生任何异常 (即之间的初始化 TransactionScope 对象并调用其 Dispose 方法),则范围所参与的事务可以继续,否则参与到其中的事务将回滚。
      当应用程序完成所有工作时它想要在事务中执行,应调用 Complete 方法一次,以通知该事务管理器是可接受(此时事务并未提交),即可提交事务,未能调用此方法中止事务。
      调用 Dispose 方法将标记事务范围的末尾。 在调用此方法之后所发生的异常不会影响事务。

二、TransactionScope有什么用?

  假如现在有一个需求:实现一个下单功能,主要业务包含扣减商品库存、扣减用户账户余额、生成订单记录以及记录日志。为了保证数据一致性我们通常的做法就是在数据库建一个下订单的事务,然后程序调用事务传入相应的参数即可。那么问题来了,如果用户的账户数据跟订单数据分别处于不同的数据库,就没法在同一个数据库事务里完成所有任务,也就没法保证数据的一致性。
  最近由于业务的变更公司改用MySQL数据库,处理数据变更时习惯性先写事务,写的时候发现现有数据库中一个事务都没有,于是去问java组,不使用事务怎么保证数据的一致性?得到的答复是:事务是什么鬼,spring帮我们解决所有问题...。立马就懵逼了,.net中没听说有Spring啊(据说有类似的框架),虽然可以考虑使用仓储加工作单元来解决,但是感觉好麻烦的样子,后来寻找解决方案时发现了TransactionScope。

三、TransactionScope怎么使用?

 try
{
using (TransactionScope scope = new TransactionScope())
{
//TODO:数据处理业务
scope.Complete();
}
}
catch (Exception ex)
{
throw ex;
}

四、问题探讨

1、准备工作

 //数据库访问对象
public class Studuent
{
public static IList<StudentModel> GetList()
{
//不允许脏读
string sql = "SELECT Id,Name,CreateTime FROM Student ORDER BY Id DESC;";
DataTable dt = SQLHelper.ExecuteDataTable(CommandType.Text, sql);
return dt.ToModel<StudentModel>();
} public static bool Add(string name)
{
SqlParameter[] parms = { new SqlParameter("@Name", SqlDbType.NVarChar, ) { Value = name } };
string sql = "INSERT INTO Student (Name) VALUES (@Name)";
return SQLHelper.ExecuteNonQuery(CommandType.Text, sql, parms) > ;
} public static void Clear()
{
SQLHelper.ExecuteNonQuery("DELETE Student");
}
}
 //公共方法,输出学生列表
static void PrintStudent()
{
IList<StudentModel> list = Studuent.GetList();
foreach (var item in list)
{
Console.WriteLine("{0}\t{1}\t{2}", Thread.CurrentThread.ManagedThreadId, item.Name, item.CreateTime);
}
Console.WriteLine();
}

2、事务什么时候提交?

最初我以为在执行Complete后即刻提交,但根据输出结果可以看出,Complete方法执行两秒之后事务依旧没有提交。因为不允许脏读的原因,主线程会在事务对Student表操作完成后才可查询完成,但学生列表是在scope调用dispose方法之后输出,MSDN介绍说dispose确定事务范围末尾,因此猜测事务是在调用dispose时被提交。

3、异常是怎么导致数据不被提交?

对比两幅图可以看出,异常在Complete之后发生并不会影响事务的提交,事务未提交是因为发生异常导致Complete未被执行。之前看过一篇文章说,如果TransactionScope范围中没有调用Complete会导致程序异常,我想他肯定是开玩笑的...

4、嵌套事务

探索逻辑事务 TransactionScope的更多相关文章

  1. 分布式事务TransactionScope

    分布式事务TransactionScope 以下是分布式事务的所有情况的例子了,包含了事务套事务,事务套存储过程事务,经过测试,TransactionScope对于分布式事务的各种情况支持的很好. 使 ...

  2. 代码块事务—TransactionScope

    今天上班遇到这样的业务:将删除的用户信息记录到记录表,再删除用户表中的信息. 可以说是不幸也可以说是幸运的. 在以往遇到这样的业务,我会考虑到各种出现异常或者失败的情况.在删除一张表数据失败的情况,对 ...

  3. 【NET Core】事务TransactionScope

    .NET FrameWork时期: TransactionScope是FCL System.Transactions命名空间下的分布式事务组件,它默认为本地事务,当系统有需要时可以自动提升为分布式事务 ...

  4. 分布式事务TransactionScope所导致几个坑

    记录一下,个人见解,欢迎指正 错误: 1.该伙伴事务管理器已经禁止了它对远程/网络事务的支持. (异常来自 HRESULT:0x8004D025)2.事务已被隐式或显式提交,或已终止3.此操作对该事务 ...

  5. C#轻量级企业事务 - TransactionScope

    using System; using System.Data.SqlClient; using System.Transactions; namespace SomeDBTransaction { ...

  6. .Net高级进阶,在复杂的业务逻辑下,如何以最简练的代码,最直观的编写事务代码?

    本文将通过场景例子演示,来通俗易懂的讲解在复杂的业务逻辑下,如何以最简练的代码,最直观的编写事务代码. 通过一系列优化最终达到两个效果,1.通过代码块来控制事务(分布式事务),2.通过委托优化Tran ...

  7. 事务使用中如何避免误用分布式事务(System.Transactions.TransactionScope)

    1:本地事务DbTransaction和分布式事务TransactionScope的区别: 1.1:System.Data.Common.DbTransaction: 本地事务:这个没什么好说了,就是 ...

  8. 如何避免误用分布式事务(System.Transactions.TransactionScope)

    以下内容来源与:http://www.cyqdata.com/cyq1162/article-detail-54453 1:本地事务DbTransaction和分布式事务TransactionScop ...

  9. 谈谈分布式事务之三: System.Transactions事务详解[下篇]

    在前面一篇给出的Transaction的定义中,信息的读者应该看到了一个叫做DepedentClone的方法.该方法对用于创建基于现有Transaction对 象的“依赖事务(DependentTra ...

随机推荐

  1. 分享一个与ABP配套使用的代码生成器源码

    点这里进入ABP系列文章总目录 分享一个与ABP配套使用的代码生成器源码 真对不起关注我博客的朋友, 因最近工作很忙, 很久没有更新博客了.以前答应把自用的代码生成器源码共享出来, 也一直没有时间整理 ...

  2. scope.$apply是干嘛的

    开始用angular做项目的时候,一定碰到过$scope.$apply()方法,表面上看,这像是一个帮助你进行数据更新的方法,那么,它为何存在,我们又该如何使用它呢. JavaScript执行顺序 J ...

  3. SQLServer 2016安装时的错误:Polybase要求安装Oracle JRE 7更新51或更高版本

    异常处理汇总-数据库系列  http://www.cnblogs.com/dunitian/p/4522990.html 水印就不加了,在老家~(另一篇文章好像没发布成功,简单说下,2016安装完毕是 ...

  4. Grunt(页面静态引入的文件地址的改变探究)-V2.0

    相关插件的引用: grunt-usemin  对页面的操作 grunt-contrib-cssmin  压缩css load-grunt-tasks 瘦身gruntfile grunt-rev给md5 ...

  5. H5 Notes:Navigator Geolocation

    H5的地理位置API可以帮助我们来获取用户的地理位置,经纬度.海拔等,因此我们可以利用该API做天气应用.地图服务等. Geolocation对象是我们获取地理位置用到的对象. 首先判断浏览器是否支持 ...

  6. php登录注册页面及加载

                           php注册界面                               <h1>注册页面</h1> <form acti ...

  7. SQL Server索引视图以(物化视图)及索引视图与查询重写

    本位出处:http://www.cnblogs.com/wy123/p/6041122.html 经常听Oracle的同学说起来物化视图,物化视图的作用之一就是可以实现查询重写,听起来有一种高大上的感 ...

  8. MVC5学习系列--Razor视图(一)

    前言 嗷~小弟我又出现了~咳咳..嚎过头了, 先说一说为什么写这个吧,~首先肯定是我自己需要学(废话 - -,)//,之前也写过MVC4的项目,嗯..但是仅限于使用并没有很深入的每个模块去了解, 这段 ...

  9. Java进击C#——应用开发之Asp.net MVC

    本章简言 上一章笔者讲到关于Asp.NET的知识点.了解Asp.NET基本的知识点之后,我们在来学习关于C#的MVC框架就简单多了.显然本章就是来介绍一下关于Asp.NET MVC.对于MVC的思想笔 ...

  10. JavaScript 随机数

    JavaScript内置函数random(seed)可以产生[0,1)之间的随机数,若想要生成其它范围的随机数该如何做呢? 生成任意范围的随机数 //生成[100,120)之间的随机数 Math.fl ...