以下内容来源与:http://www.cyqdata.com/cyq1162/article-detail-54453

1:本地事务DbTransaction和分布式事务TransactionScope的区别:

1.1:System.Data.Common.DbTransaction:

本地事务:这个没什么好说了,就是单个事务,每种数据库都有自己的实现,事务的深度内涵可以搜索查看相关的文章,不是本文介绍的重点。

1.2:System.Transactions.TransactionScope:

分布式事务,需要添加引用System.Transactions,同时启用MSDTC分布式事务服务:通常使用方式为:

 using (System.Transactions.TransactionScope ts = new System.Transactions.TransactionScope())
 {
                //代码块A
                //代码块B
                ts.Complete();//提交事务
 }

分布式事务本质上是引入了第三方裁判,来想办法对多个本地事务监控同时成功或同时失败,这里分享几个知识点:

A:如果代码块里,若存在两个或以上数据库链接DbConnection,则需要启动微软的MSDTC分布式事务服务。

用命令行启动或停止服务:

B:如果代码块里,只有一个数据库链接DbConnection,那么实际上只是本地事务在处理,就算MSDTC分布式事务服务没启动,也不会报错。

C:对于TransactionScope包含的代码块,本质是监控了代码块里数据库链接DbConnection的个数,如果有多个不同的对象,则引入MSDTC当裁判,而实际执行的事务的还是各个本地事务。

D:MSDTC总是不够稳定,我在测试时两个简单的事务一起时,按住F5不停刷新,竟然能把MSSQL服务也给挂了,而用本地事务就算跨库也不会有问题。

所以,不是必须的情况,尽量不要引入分布式事务,应该避免使用TransactionScope来包含事务块的冲动。

2:可以用本地事务解决,避免使用分布式事务场景:

2.1:项目只有一个数据库,这个是最应该避免,多个表间的事务, 完全是本地事务可处理的范围:

问题:一个代码块里N个实体类杂交操作,每个实体类带有各种的数据库链接,从而引发了MSDTC。

可以:共用一个DbConnection对象,来避免启用MSDTC。

2.2:项目多个数据库,如果数据库间使用了相同的访问账号和密码,这种情况也可以避免:

每种数据库有自己的解决方式:像MSSQL,跨库处理只要加前缀(dbname..tablename)就可以,因此也使的只使用本地事务就可以处理了。

3:回顾下我以前的项目场景:

3.1:从下图是我08年在中域的项目:有19个数据库,对于数据库链接而言,唯一的不同只有数据库的名称:

进化:能不能只保留一条,其它的通过动态切换数据库名称来改链接字符串?

3.2:那时候,我的架构还是很新手,通过CodeSmith生成了大量的代码文件:

实体类项目,工厂项目,接口项目,数据操作,还有大量的增删改查存储过程,只是为了基础的增删改查而且只针对MSSQL。

随便展开一个项目都会看到大量的文件夹,里面有大量的文件,而这些东东,都是代码生成器的杰作:

 

19个数据库啊,NN个表,光生成这些基本的增删改查,整个项目就好像高端大气上档次了。

进化:能不能消灭这些大量的文件,简单是我们不断追求的目标。

3.3:这么多数据库,如何跨数据库事务?

对于生成的大量的实体,每个表的操作都是一个新的链接,单库间的事务都必须MSDTC了,更别说19个库间的跨库事务了。

进化:能不能本地事务搞定这些,这是每个ORM可以思考的方向。

4:CYQ.Data 提供的解决方案:

为了消灭上述的那些大量的生成文件,我在后续新的公司写了传统的ORM框架:XQData(这个框架一直没露过面,也只是支持MSSQL,用反射消灭了好多层,只留下实体层)。

对于框架的演进,多数都来源于项目中遇到的问题,或复杂的场景,需要解决或者简化,才有了不断升级的可能,并不是无中生有,因此,一个框架,如果不能不断在在项目中实战,那么很多问题和细节等可能都无法发现,更新也会遥遥无期。

而CYQ.Data的不断升级,说明我一直在奋战在一线的编码生涯中和网友各大项目中的实战反馈中。

下面针对最近的优化调整,演示下CYQ.Data是怎么解决上面提到的几个问题:

4.1:多个数据库的数据库链接切换:

A:先用配置工具生成针对多数据库的枚举文件,和成demo和test两个数据库:

两个数据库就生成两次了。

B:配置一个默认的链接字符串,到Demo数据库:

<add name="Conn" connectionString="server=.;database=demo;uid=sa;pwd=123456"/>

C:打印操作Test数据库表的链接字符串:

using (MAction action = new MAction(TestEnum.Users))
            {
                Console.WriteLine(action.ConnectionString);
            }

输出:

这里自动切换了数据为名称为新的链接,而我动手脚的地方就是在枚举的名称了。

4.2:本地多数据库跨事务,示例:

            AppDebug.OpenDebugInfo = true;
            AppDebug.Start();
            using (MAction action = new MAction(DemoEnum.Users))
            {
                 action.BeginTransation();//开启事务
                 action.Fill(12);
                Console.WriteLine(action.ConnectionString);//打印数据库链接
                action.ResetTable(TestEnum.Users);//切换数据库
                Console.WriteLine(action.ConnectionString);//打印数据库链接
                action.Fill(12);
                action.EndTransation();
            }
            Console.WriteLine(AppDebug.Info);//输出所有执行的SQL语句。
            AppDebug.Stop();

输出的结果:

说明:在事务中,当检测到事务开启时,为了使用本地事务,并没有切换数据库,而是采用了前缀来执行操作。

如果注释掉代码中的事务,则是直接切换数据库链接,输出会如下图:

说明:如果没有开启事务,则直接切换了数据库链接,并消消灭前缀语法。

总结:

对于.NET领域,微软除了提供这个不太稳定的MSDTC,似乎没有发现其它分布式事务的解决方案,好在一般的项目,我们在本地事务就可以处理。

希望微软可以在一些重点分布式上多做点研究、普及和推广,提供大型项目的解决方案,别整天操碎心在那些简单的增删改查上。

如何避免误用分布式事务(System.Transactions.TransactionScope)的更多相关文章

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

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

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

    在.NET 1.x中,我们基本是通过ADO.NET实现对不同数据库访问的事务..NET 2.0为了带来了全新的事务编程模式,由于所有事务组件或者类型均定义在System.Transactions程序集 ...

  3. 关于分布式事务的一个误解:使用了TransactionScope就一定会开启分布式事务吗?

    背景: 事务是数据库管理系统的一个基本概念,事务具有四个基本特点,即ACID:原子性(Atomicity).一致性(Consistency).隔离性(Isolation)和持久性(Durability ...

  4. .NET分布式事务--TransactionScop

    一.开启DTC服务 方式一 计算机—管理—服务—Distributed Transaction Coordinator—属性—开启 方式二 CMD命令子界面输入:net start msdtc 二.设 ...

  5. 【WCF--初入江湖】07 分布式事务

    07 分布式事务 一.前言 [1]理解事务特性 [2]掌握TransactionFlow 特性 [3]掌握WCF中的事务属性 TransactionAutoCompleteOnSessionClose ...

  6. ASP.NET中分布式事务的使用

    之前发表了一篇事务的存储过程,最近在做项目的时候遇到分布式事务,所有总结一下,跟大家分享和交流一下经验.首先说明为什么要分布式事务呢?先说说我在项目的哪里遇到分布式事务吧,我是在做网站后台开发的时候, ...

  7. WCF分布式开发步步为赢(12):WCF事务机制(Transaction)和分布式事务编程

    今天我们继续学习WCF分布式开发步步为赢系列的12节:WCF事务机制(Transaction)和分布式事务编程.众所周知,应用系统开发过程中,事务是一个重要的概念.它是保证数据与服务可靠性的重要机制. ...

  8. EF 事务(非分布式事务)

    在EF 中怎么使用事务? 这个问题纠结了我好久,直到有人跟我一起讨论,我和同事一起讨论查资料. 查的好多资料都是使用 TransactionScope,用 TransactionScope 可处理分布 ...

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

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

随机推荐

  1. ORACLE查看和更改的最大连接数

     第一步,在cmd命令行,进入sqlplus 第二步骤,根据提示输入username与password 1. 视图processes和sessions参数 SQL> show paramet ...

  2. Hadoop之环境搭建

    初学Hadoop之环境搭建   阅读目录 1.安装CentOS7 2.安装JDK1.7.0 3.安装Hadoop2.6.0 4.SSH无密码登陆 本文仅作为学习笔记,供大家初学Hadoop时学习参考. ...

  3. Atitit.异步编程 java .net php python js 对照

    Atitit.异步编程 java .net php python js 的比較 1. 1.异步任务,异步模式,  APM模式,,  EAP模式, TAP 1 1.1.       APM模式: Beg ...

  4. IOS开发-Swift新语言初见

    Safe Swift pairs increased type safety with type inference, restricts direct access to pointers, and ...

  5. 写给初学前端工程师的一封信 (转于Kejun)

    大家好: 应波波的邀请写一写我对这个话题的想法.从去年开始不少朋友让我帮忙介绍前端工程师,绝大部分忙都没帮上,原因是真找不到人.我当时是这么跟他们分析的:过去的客户端以browser为主,所以HTML ...

  6. 探究Java中Map类

    Map以按键/数值对的形式存储数据,和数组非常相似,在数组中存在的索引,它们本身也是对象.       Map的接口       Map---实现Map       Map.Entry--Map的内部 ...

  7. 日积月累系列之分页控件(js源码)

    最近开发了一款分页控件,分享给大家. 主要功能和界面介绍 cform分页控件支持服务端分页.客户端分页.数据过滤.数据排序等功能. 源码介绍 cform-pager分页控件主要由三部分组成:css.s ...

  8. PHP 17: MySQL的简单介绍

    原文:PHP 17: MySQL的简单介绍 这一章将简单介绍MySQL的基本知识. 本文来自http://lib.hackbase.com/html/8/35125.htm. MySQL是最受欢迎的开 ...

  9. 打印Ibatis最后,SQL声明

    做项目时,满足这一需求.我们希望最终打印出在数据库运行SQL声明,这些都普遍遇到了一些一般性问题.我会去Appfuse,结果这次没有成功.它是有相关的配置,可是好像没实用.我也就没有深查下去.我想这种 ...

  10. Invent 2014回顾

    AWS re:Invent 2014回顾   亚马逊在2014年11月11-14日的拉斯维加斯举行了一年一度的re:Invent大会.在今年的大会上,亚马逊一股脑发布和更新了很多服务.现在就由我来带领 ...