术语:DTC(分布式事务协调器)

.Net中实现事务的几种方法总结:
一、 通过后台数据库的SQL语句实现事务,在台数据库端通过语句来实现转帐业务,如下:

Set xact_abort on

Begin tran

Update A_user set balance = balance -10000 where uid=’211705’

Update B_user set balance = balance + 10000 where uid=’462509’

Commit tran

其中Set xact_abort on 很重要,要没有的话,数据库就不会自动回滚出现错误的事务。

也可以手动实现回滚事务,代码如下:

Declare @a_userError int,

Declare @b_userError int

Begin tran

Update A_user set balance = balance -10000 where uid=’211705’

Set @a_userError = @@Error

Update B_user set balance = balance + 10000 where uid=’462509’

Set @b_userError = @@Error

If @a_userError=0 and @b_userError=0 then

Begin

Commit tran

Return (1) -- return 1 meaning is Trans commit successful

End

Else

Begin

Rollback tran

Return (0) – return 0 meaning is Trans commit failed

End

手动回滚的语句多一些,但是有返回值,以便在程序中判断是否执行成功。
二、 通过ADO.NET组件实现事务:

通过***Transaction实现事务,是在数据库连接上创建事务处理对象,然后调用事务处理对象来提交或回滚事务,前面转账的例子:

SqlConnection conn = new SqlConnection(“”);

Conn.Open();

SqlTransaction tran = Conn.BeginTransaction();

SqlCommand cmd = new SqlCommand();

cmd.connection = Conn;

cmd.Transaction = tran;

try

{

cmd.CommandText = “Update A_user set balance = balance -10000 where uid=’211705’”;

cmd.ExecuteNonQuery();

cmd.CommandText = “Update B_user set balance = balance + 10000 where uid=’462509’”;

cmd.ExecuteNonQuery();

tran.Commit();

}

Catch(Exception ex)

{

Tran.Rollback();

}

这种方式实现的事务提交的代码结构很清晰,但是在硬编码事务的情况下,任何修改业务逻辑或用户需求的改变都需要重新修改并编译源代码。

三、通过COM+提供的事务支持实现事务处理:

在.NET中要访问COM+提供的事务支持,首先必须把.NET程序集注册到COM+组件容器中,要把.NET程序集注册到COM+中必须满足以下条件:

a. 程序集必须使用强名称签名

b. 程序集内包含的类必须从ServicedComponent类继承

c. 程序集必须添加到特定的COM+应用程序中

d. 程序集必须在Windows注册表中注册

1) 首先在.NET命令中使用sn.exe工具生成强名称,如sn –k test.snk,将生成的密钥文件拷到程序目录下,然后在assemblyinfo.cs修改assemblykeyfile路径,如:

[assembly:assemblykeyFile(“..\\test.snk”)]

2) 从ServicedComponent类继承,要从该类继承必须先引入System.EnterpriseService.dll类库。

3) 声明程序集加入COM+应用程序名称,如:[assembly:applicationName(“testComplus”)]

这行代码必须添加到类文件中,而且在using指令后类代码定义之前。

这样就可以在类代码中通过ContextUtil类来调用COM+提供的上下文环境来实现事务处理了,如下代码:

Using system.EnterpriseServices;

Using System.Data.SqlClient;

//声明当前组件添加到COM+中名为testComplus应用程序内。

[assembly:applicationName(“testComplus”)]

Namespace complusAppDemo

{

//使用transaction属性声明当前组件需要COM+提供事务支持

[Transaction(TransactionOption.Required)]

Public class TransactionDemo:ServicedComponent

{

Public TransactionDemo(){}

Public bool TransDemo()

{

SqlConnection conn = new SqlConnection(“”);

Conn.Open();

SqlCommand cmd = new SqlCommand();

cmd.connection = Conn;

try

{

cmd.CommandText = “Update A_user set balance = balance -10000 where uid=’211705’”;

cmd.ExecuteNonQuery();

cmd.CommandText = “Update B_user set balance = balance + 10000 where  uid=’462509’”;

cmd.ExecuteNonQuery();

ContextUtil.SetComplete();  //调用COM+上下文提交数据

Return true;

}

Catch(Exception ex)

{

ContextUtil.SetAbout();  //调用COM+上下文回滚事务

Return false;

}

}

}

}

代码与使用ADO.NET实现事务处理的代码很相似,但是他们执行的原理不同,ADO.NET的SqlTransaction类实现事务时调用后台数据库的事务处理引擎,而COM+事务调用的COM+支持的DTC(Distributed Transaction Coordinator分布式事务协同器)服务来实现。

将项目编译为complusAppDemo.dll后,用regsvcs.exe工具首先把complusAppDemo.dll组件的类型信息写入系统注册表,然后再根据[assembly:applicationName(“testComplus”)]创建一个COM+应用程序,并将组件添加到该应用程序中。这样就可以在应用程序中调用TransactionDemo类的TransDemo()方法来实现事务处理。

四、使用.NET的事务组件,System.Transactions命名空间下的TransactionScope对象。

using (TransactionScope ts = new TransactionScope(TransactionScopeOption.Required))

{

dal.Insert(order);

// Update the inventory to reflect the current inventory after the order submission

Inventory inventory = new Inventory();

inventory.TakeStock(order.LineItems);

// Calling Complete commits the transaction.

// Excluding this call by the end of TransactionScope's scope will rollback the transaction

ts.Complete();

}

五、分布式事务处理

前面说的都是基于单个数据库实现的事务处理,但若要处理的两条或多天业务位于不同的地方的数据库时,就要跨数据库实现事务处理,这就需要使用分布式事务处理技术。在.NET框架编程中,我们可以通过两种不同的方式实现分布式事务处理:基于数据库的链接服务器和基于COM+来实现。

a. 基于链接服务器实现分布式事务处理:

首先我们需要构建链接服务器,参考SQL Server联机帮助,构建好链接服务器后在SQL Server管理器中就可以看到远程服务器了。然后就可以编写如下SQL语句实现分布式事务了:

SET XACT_ABORT_ON

Begin distributed tran

Update A_user set balance = balance -10000 where uid=’211705’

Update BCENTER.northwind.dbo.B_user set balance = balance + 10000 where uid=’462509’

Commit tran

与单台数据库服务器事务处理不一样的地方是第2行和第4行,其中第2行声明当前事务处理为分布式事务处理,第4行声明对BCENTER服务器上的northwind数据库的B_user数据表操作。

所以这种实现分布式的方式在编码上比较简单,但是配置和部署的工作量增加了,因为我们首先需要建立链接服务器。

b. 基于COM+实现

通过COM+实现分布式事务处理与实现单个数据库的事务处理都是通过DTC(分布式事务协调器)来实现的,但是分布式事务处理在原理上与单台服务器是有差异的。COM+实现分布式事务处理时,需要DTC的事务处理引擎与不同数据库的事务管理器通讯,发送需要执行的事务操作,数据库的事务管理器在执行该操作后将结果返回到DTC,如果所有的事务管理器返回的都是正确信息,则DTC发出提交指令到各个数据库事务管理器,数据修改提交的后台数据库,分布式事务完成。如果有任何一个数据库事务管理器返回错误信息,则DTC发出回滚指令,分布式事务撤销。这就是两阶段提交的分布式事务操作。

代码与实现单个数据库的事务处理很相似,只需在两个不同的数据库连接上执行这两个command命令。

比较上述两种不同的分布式事务处理方式,我们可以看出使用链接服务器实现分布式事务时部署起来比较麻烦,而使用COM+实现则部署方便,但是链接服务器实现的分布式事务可以封装为存储过程,将来修改业务逻辑升级应用程序比较方便,而通过COM+实现时一旦业务规则改变就需要重新修改和编译代码。

来自西北的狼!

事务处理笔记《二》.Net框架下的事务处理技术的更多相关文章

  1. Docker学习笔记二(linux下安装Docker)

    Docker学习笔记二(linux下安装Docker) 1.在线安装linux Docker 这种方式首先要保证linux 环境下可以上网,当然,小编是在自己的电脑上安装了虚拟机,在虚拟机上安装了,l ...

  2. 蜗牛历险记(二) Web框架(下)

    Web框架第三篇--缓存篇 缓存的优劣很大程度上决定了框架的效率,一个有节操的缓存它应该是高效的,利用率高的,具备更多扩展功能的. 一.介绍之前 计算机各个硬件的运行效率是不一样的,CPU>&g ...

  3. Thrift笔记(二)--Thrift框架分层设计

    thrift架构设计使用了分层设计,类似TCP/IP分层,上次使用下层提供的服务.分层设计在计算机中是一个常用的设计,上层和下层定义好接口或者说协议,下层实现可以随意更换,只要实现好定义的接口和协议就 ...

  4. 初探Net框架下的XML编程技术

    一.前言: XML是微软.Net战略的一个重要组成部分,而且它可谓是XML Web服务的基石,所以掌握.Net框架下的XML技术自然显得非常重要了.本文将指导大家如何运用C#语言完成.Net框架下的X ...

  5. 【工作笔记二】ASP.NET MVC框架下使用MVVM模式

    ASP.NET MVC框架下使用MVVM模式 原文:http://www.cnblogs.com/n-pei/archive/2011/07/21/2113022.html 对于asp.net mvc ...

  6. JEECG(二) JEECG框架下调用webservice java springmvc maven 调用 webservice

    JEECG系列教程二 如何在JEECG框架下使用webservice 本文所使用的webservice是c#开发的 其实无论是什么语言开发的webservice用法都一样 java springmvc ...

  7. keras框架下的深度学习(二)二分类和多分类问题

    本文第一部分是对数据处理中one-hot编码的讲解,第二部分是对二分类模型的代码讲解,其模型的建立以及训练过程与上篇文章一样:在最后我们将训练好的模型保存下来,再用自己的数据放入保存下来的模型中进行分 ...

  8. nodejs学习笔记二:解析express框架项目文件

    上一章介绍了如何去创建一个express框架的工程项目,这章介绍一下express框架下的文件和用法解析,上一张我们创建的工程项目结构图如下: models是不属于原工程项目结构,为了实现数据模型后添 ...

  9. 深入剖析 RabbitMQ —— Spring 框架下实现 AMQP 高级消息队列协议

    前言 消息队列在现今数据量超大,并发量超高的系统中是十分常用的.本文将会对现时最常用到的几款消息队列框架 ActiveMQ.RabbitMQ.Kafka 进行分析对比.详细介绍 RabbitMQ 在 ...

随机推荐

  1. Node.js meitulu图片批量下载爬虫 1.05版(Final最终版)

    //====================================================== // https://www.meitulu.com图片批量下载Node.js爬虫1. ...

  2. 记录一个奇妙的Bug, -1 >= 2 ?

    直接上代码: #include <iostream> #include <vector> using namespace std; int main() { vector< ...

  3. Scapy基础学习之中的一个

    关于Scapy Scapy的是一个强大的交互式数据包处理程序(使用python编写). 它可以伪造或者解码大量的网络协议数据包,可以发送.捕捉.匹配请求和回复包等等.它可以非常easy地处理一些典型操 ...

  4. jQuery-DesktopGrid

    jQueryDesktopGrid jQueryDesktopGrid migrate to https://github.com/jelly-liu/jquery-osx jQuery deskto ...

  5. win10 为了对电脑进行保护,已经阻止此应用 解决方法

        win10 为了对电脑进行保护,已经阻止此应用 解决方法 正确方法: ."win+x"进入控制面板,选择安全性与维护,在左侧更改windows smartscreen筛选器 ...

  6. python列表解析和正同表达式

    正则表达式 [i for i in ['1232','233','22'] if re.match('^233$', i)]   return  ['233']

  7. 浅谈Android移动开发程序员的职业发展之路

    现在几乎每个it公司都在开发移动产品,我最早知道Android还是在09年成都某学院上大学的时候,从新闻上知道有这么一家公司,创始人安迪·鲁宾很有名,但安卓到底是做什么的,我并没有关注. 到2010年 ...

  8. 在Eclipse中导入dtd和xsd文件,使XML自动提示(转)

    DTD 类型约束文件 1. Window->Preferences->XML->XML Catalog->User Specified Entries窗口中,选择Add 按纽 ...

  9. 一个由正则表达式引发的血案 vs2017使用rdlc实现批量打印 vs2017使用rdlc [asp.net core 源码分析] 01 - Session SignalR sql for xml path用法 MemCahe C# 操作Excel图形——绘制、读取、隐藏、删除图形 IOC,DIP,DI,IoC容器

    1. 血案由来 近期我在为Lazada卖家中心做一个自助注册的项目,其中的shop name校验规则较为复杂,要求:1. 英文字母大小写2. 数字3. 越南文4. 一些特殊字符,如“&”,“- ...

  10. Linux 常用命令速查

    0x001 .在指定文件夹下递归查询包含一个字符串的文件(列出的文件内容片段) grep -r   “要查找的串”    文件路径   如  : grep -r  "helloworld&q ...