探索逻辑事务 TransactionScope
一、什么是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的更多相关文章
- 分布式事务TransactionScope
分布式事务TransactionScope 以下是分布式事务的所有情况的例子了,包含了事务套事务,事务套存储过程事务,经过测试,TransactionScope对于分布式事务的各种情况支持的很好. 使 ...
- 代码块事务—TransactionScope
今天上班遇到这样的业务:将删除的用户信息记录到记录表,再删除用户表中的信息. 可以说是不幸也可以说是幸运的. 在以往遇到这样的业务,我会考虑到各种出现异常或者失败的情况.在删除一张表数据失败的情况,对 ...
- 【NET Core】事务TransactionScope
.NET FrameWork时期: TransactionScope是FCL System.Transactions命名空间下的分布式事务组件,它默认为本地事务,当系统有需要时可以自动提升为分布式事务 ...
- 分布式事务TransactionScope所导致几个坑
记录一下,个人见解,欢迎指正 错误: 1.该伙伴事务管理器已经禁止了它对远程/网络事务的支持. (异常来自 HRESULT:0x8004D025)2.事务已被隐式或显式提交,或已终止3.此操作对该事务 ...
- C#轻量级企业事务 - TransactionScope
using System; using System.Data.SqlClient; using System.Transactions; namespace SomeDBTransaction { ...
- .Net高级进阶,在复杂的业务逻辑下,如何以最简练的代码,最直观的编写事务代码?
本文将通过场景例子演示,来通俗易懂的讲解在复杂的业务逻辑下,如何以最简练的代码,最直观的编写事务代码. 通过一系列优化最终达到两个效果,1.通过代码块来控制事务(分布式事务),2.通过委托优化Tran ...
- 事务使用中如何避免误用分布式事务(System.Transactions.TransactionScope)
1:本地事务DbTransaction和分布式事务TransactionScope的区别: 1.1:System.Data.Common.DbTransaction: 本地事务:这个没什么好说了,就是 ...
- 如何避免误用分布式事务(System.Transactions.TransactionScope)
以下内容来源与:http://www.cyqdata.com/cyq1162/article-detail-54453 1:本地事务DbTransaction和分布式事务TransactionScop ...
- 谈谈分布式事务之三: System.Transactions事务详解[下篇]
在前面一篇给出的Transaction的定义中,信息的读者应该看到了一个叫做DepedentClone的方法.该方法对用于创建基于现有Transaction对 象的“依赖事务(DependentTra ...
随机推荐
- FASTDFS调研报告(V1.0)
之前的文章,现在放出来,以供参阅. 一.fastdfs简介 FastDFS是一个轻量级的开源分布式文件系统 FastDFS主要解决了大容量的文件存储和高并发访问的问题,文件存取时实现了负载均衡 Fas ...
- Web API与OAuth:既生access token,何生refresh token
在前一篇博文中,我们基于 ASP.NET Web API 与 OWIN OAuth 以 Resource Owner Password Credentials Grant 的授权方式( grant_t ...
- linux poll函数
poll函数与select函数差不多 函数原型: #include <poll.h> int poll(struct pollfd fd[], nfds_t nfds, int timeo ...
- 学习JVM--垃圾回收(一)原理
1. 前言 Java和C++之间显著的一个区别就是对内存的管理.和C++把内存管理的权利赋予给开发人员的方式不同,Java拥有一套自动的内存回收系统(Garbage Collection,GC)简称G ...
- Java 二叉树遍历右视图-LeetCode199
题目如下: 题目给出的例子不太好,容易让人误解成不断顺着右节点访问就好了,但是题目意思并不是这样. 换成通俗的意思:按层遍历二叉树,输出每层的最右端结点. 这就明白时一道二叉树层序遍历的问题,用一个队 ...
- 单链表的C++实现(采用模板类)
采用模板类实现的好处是,不用拘泥于特定的数据类型.就像活字印刷术,制定好模板,就可以批量印刷,比手抄要强多少倍! 此处不具体介绍泛型编程,还是着重叙述链表的定义和相关操作. 链表结构定义 定义单链表 ...
- visual formatting model (可视化格式模型)【持续修正】
概念: visual formatting model,可视化格式模型 The CSS visual formatting model is an algorithm that processes a ...
- Java 单例模式详解
概念: java中单例模式是一种常见的设计模式,单例模式分三种:懒汉式单例.饿汉式单例.登记式单例三种. 单例模式有一下特点: 1.单例类只能有一个实例. 2.单例类必须自己自己创建自己的唯一实例. ...
- Struts2配置国际化资源
1. 国际化的目标 1). 如何配置国际化资源文件 I. Action 范围资源文件: 在Action类文件所在的路径建立名为 ActionName_language_country.properti ...
- Python 操作 MS Excel 文件
利用 Python 对 Excel 文件进行操作需要使用第三方库: openpyxl,可执行 pip install openpyxl 进行安装 1. 导入 openpyxl 模块 导入 openpy ...
