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();

                Console.WriteLine(action.ConnectionString);//打印数据库链接

                action.ResetTable(TestEnum.Users);//切换数据库

                Console.WriteLine(action.ConnectionString);//打印数据库链接

                action.Fill();

                action.EndTransation();

            }

            Console.WriteLine(AppDebug.Info);//输出所有执行的SQL语句。

            AppDebug.Stop();

输出的结果:

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

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

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

总结:

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

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

新的一年,要重新卖身了,打算漂泊,城市不限,欢迎大伙推荐买主,谢谢。

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

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

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

  2. 【RocketMQ】【分布式事务】使用RocketMQ实现分布式事务

    参考地址:https://blog.csdn.net/zyw23zyw23/article/details/79070044 视频地址:https://v.youku.com/v_show/id_XO ...

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

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

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

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

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

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

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

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

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

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

  8. WCF分布式事务(EF)

    才说分布式事务,首先,了解一下什么是交易. 事务有四个特性:ACID A是Atomicity,原子性.一个事务往往涉及到很多的子操作,原子性则保证这些子操作要么都做,要么都不做,而不至于出现事务的部分 ...

  9. C#分布式事务解决方案-TransactionScope

    引用一下别人的导读:在实际开发工作中,执行一个事件,然后调用另一接口插入数据,如果处理逻辑出现异常,那么之前插入的数据将成为垃圾数据,我们所希望的是能够在整个这个方法定义为一个事务,Transacti ...

随机推荐

  1. 手把手教你玩转nginx负载均衡(一)----使用vitualBox创建虚拟机

    引言 作为一个web程序员,有时候需要想尽办法来利用有限的资源来产生最大程度的负载,除了提高硬件配置,增加带宽之外,CDN加速,DNS加速,缓存,还可以利用反向代理.但是要说反向代理,就不的不说ngi ...

  2. node.js express架构安装部署

    安装-g:表示全局安装(必须以安装node.js) npm install -g express-generator 创建一个express架构的项目文件夹express testWebApp 在pa ...

  3. Oracle执行计划详解

    Oracle执行计划详解 --- 作者:TTT BLOG 本文地址:http://blog.chinaunix.net/u3/107265/showart_2192657.html --- 简介:   ...

  4. 剑指Offer-【面试题07:两个栈实现队列】

    package com.cxz.question7; import java.util.Stack; /** * 用两个栈实现一个队列.队列的声明如下,请实现它的两个函数appendTail 和del ...

  5. Remove Duplicates from Sorted Array II

    题目简述 Follow up for "Remove Duplicates": What if duplicates are allowed at most twice? For ...

  6. 如何把Qlik Sense嵌入到Web应用中

    (此文章同时发表在本人微信公众号"dotNET开发经验谈",欢迎右边二维码来关注.) 题记:这是一个给初学者(尤其对VS不熟悉的BI工程师)的入门操作向导. Qlik Sense是 ...

  7. 解决报错 ora-00704 ora-00604 ora-00942 启动不了数据库问题

    早上海南的同事打电话说他们的审计库连不上了启动也报错,问了下最近做了些什么操作,答复是之前添加了一次磁盘. 猜测是添加磁盘启动后/dev/sdx顺序出错,或者没有正常的关闭数据库导致数据库无法正常启动 ...

  8. PowerDesigner导出SQL脚本

    1. 先创建E-R图模型

  9. 自用VS Code 上的Markdown 编辑器css

    目标效果如下: 主题使用:Markdown Yellow 主题[https://marketplace.visualstudio.com/items?itemName=ms-vscode.Theme- ...

  10. 主机ping不同虚拟机

    前提:今天加班时,一不小时把网线踢掉了,然而虚拟机怎么都ping不通了,试过很多办法; 最后.... 简单粗暴的重启了我的主机,对,是主机,不是虚拟机,ok,问题解决; over...