一、什么是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. .NET 环境中使用RabbitMQ

    在企业应用系统领域,会面对不同系统之间的通信.集成与整合,尤其当面临异构系统时,这种分布式的调用与通信变得越发重要.其次,系统中一般会有很多对实时性要求不高的但是执行起来比较较耗时的地方,比如发送短信 ...

  2. ASP.NET MVC Model绑定(六)

    ASP.NET MVC Model绑定(六) 前言 前面的篇幅对于IValueProvider的使用做个基础的示例讲解,但是没并没有对 IValueProvider类型的实现做详细的介绍,然而MVC框 ...

  3. iOS-----正则表达式的基础语法

    正则表达式简单语法总结 一.什么是正则表达式 从概念上来说,正则表达式也是一门小巧而精炼的语言,它可以用来简化检索特定的字符串,替换特定字符等功能,有许多开发语言工具,都内嵌支持正则表达式.那么一个正 ...

  4. SubSonic3.0使用存储过程查询时,不能使用output参数返回值的问题修改

    有个群友问SubSonic3.0执行存储过程时能不能使用output参数返回值,说测试过后获取不到返回值,早上有些时间所以就尝试修改了一下 首先在数据库中创建一个存储过程 CREATE PROCEDU ...

  5. webService学习之路(三):springMVC集成CXF后调用已知的wsdl接口

    webService学习之路一:讲解了通过传统方式怎么发布及调用webservice webService学习之路二:讲解了SpringMVC和CXF的集成及快速发布webservice 本篇文章将讲 ...

  6. jQuery2.x源码解析(构建篇)

    jQuery2.x源码解析(构建篇) jQuery2.x源码解析(设计篇) jQuery2.x源码解析(回调篇) jQuery2.x源码解析(缓存篇) 笔者阅读了园友艾伦 Aaron的系列博客< ...

  7. [Spring]01_环境配置

    )在资源库界面点击Artifacts标签,然后点击libs-release-local,展开后依次点击org -> springframework -> spring.

  8. css3新单位学习

    vw,vh,vmin,vmax vw 1vw = 视窗width*1% vh 1vh = 视窗heihgt*1% 如果视窗的宽度小于高度,1vmin = 1vw,如果视窗宽度大于高度,1vmin = ...

  9. STM32F746的RTC使用

    1.RTC模块采用低速晶振外接始终:32.768KHz,如下图所示 2.配置RTC模块: 其中,Fck_apre.Fck_spre始终上配置不容易理解, 如果想得到1Hz的始终频率,则需要将PERDI ...

  10. visual studio 编辑窗口 设置固定选项卡 使窗口选项卡多行显示

    工具>选项> 确定后 如图就可以多行显示了.