C#中跨库事务控制(二)

来源:互联网 发布:手机价格评估软件 编辑:程序博客网 时间:2024/06/06 09:44

C#中跨库事务控制(二)

.NET Framework 2.0 版引入了一个可通过 System.Transactions 命名空间访问的事务框架。此框架公开事务的方式是完全集成在 .NET Framework,包括 ADO.NET。

除了对编程能力的增强之外,System.Transactions 与 ADO.NET 可一起使用,在处理事务时协调优化。可提升事务是可以根据需要自动提升为完全分布式事务的轻型(本地)事务。

从 ADO.NET 2.0 开始,当您使用 SQL Server 2005 时 System.Data.SqlClient 会提供对可提升事务的支持。可提升的事务不会调用分布式事务增加的系统开销,除非需要增加的系统开销。可提升事务是自动的,不需要开发人员参与。

只有一起使用 SQL Server 的 .NET Framework 数据提供程序 (SqlClient) 和 SQL Server 2005 时,才可以使用可提升事务。

创建可提升事务

SQL Server 的 .NET Framework 提供程序支持可提升事务,这种事务通过 .NET Framework System.Transactions 命名空间中的类处理。可提升事务通过将分布式事务推迟到需要时再创建,对分布式事务进行优化。如果只需要一个资源管理器,则不会发生任何分布式事务。

 

说明:

在部分信任方案中,将事务提升为分布式事务时,需要 DistributedTransactionPermission。有关更多信息,请参见事务管理升级。

可提升事务方案

分布式事务由 Microsoft 分布式事务处理协调器 (MS DTC) 管理,该协调程序集成了事务中访问的所有资源管理器,通常会占用大量的系统资源。可提升事务是 System.Transactions 事务的一种特殊形式,有效地将工作委托给简单的 SQL Server 2005 事务。System.Transactions、System.Data.SqlClient 和 SQL Server 2005 协调在处理事务时涉及到的工作,根据需要将其提升为完全分布式事务。

使用可提升事务的优点是在使用活动 TransactionScope 事务打开某个连接但不打开任何其他连接时,事务作为轻型事务提交,而不引发完全分布式事务的其他系统开销。

连接字符串关键字

ConnectionString 属性支持关键字 Enlist,该关键字指示 System.Data.SqlClient 是否将检测事务上下文并自动在分布式事务中登记连接。如果 Enlist=true,连接将自动在打开的线程的当前事务上下文中登记。如果 Enlist=falseSqlClient 连接不会与分布式事务进行交互。Enlist 的默认值为 true。如果连接字符串中未指定 Enlist,而在连接打开时检测到一个连接,连接将自动在分布式事务中登记。

SqlConnection 连接字符串中的 Transaction Binding 关键字控制连接与已登记的 System.Transactions 事务的关联。还可以通过 SqlConnectionStringBuilder 的 TransactionBinding 属性使用。

下表说明可用的值。

关键字

说明

隐式取消绑定

默认值。事务结束时,连接与事务分离,切换回自动提交模式。

显式取消绑定

事务关闭之前,连接保持附加到事务。如果关联的事务未处于活动状态或不匹配 Current,则连接将失败。

有关更多信息,请参见使用事务范围实现隐式事务。

使用 TransactionScope

TransactionScope 类通过隐式在分布式事务中登记连接,使代码块事务化。必须在 TransactionScope 块的结尾调用 Complete 方法,然后再离开该代码块。离开代码块将调用 Dispose 方法。如果引发的异常造成代码离开范围,将认为事务已中止。

我们建议您使用 using 块,以确保在退出 using 代码块时,在 TransactionScope 对象上调用 Dispose。如果无法提交或回滚挂起的事务,可能会对性能造成严重影响,因为 TransactionScope 的默认超时为一分钟。如果不使用 using 语句,必须在 Try 代码块中执行所有工作,并在 Finally 代码块中显式调用 Dispose 方法。

如果在 TransactionScope 中发生异常,事务将标记为不一致并被弃用。在 TransactionScope 断开后,事务将回滚。如果未发生任何异常,参与的事务将提交。

说明:

默认情况下,TransactionScope 类将创建一个 IsolationLevel 为 Serializable 的事务。根据应用程序的不同,可能需要考虑降低隔离级别,以避免应用程序中出现大量的争用。

说明:

我们建议您只在分布式事务中执行更新、插入和删除,因为这些操作会占用大量的数据库资源。选择语句可能会对数据库资源进行不必要的锁定,在某些方案中,可能需要使用事务进行选择。任何非数据库工作应在事务范围之外完成,除非工作涉及其他事务化的资源管理器。尽管事务范围内的异常会使事务无法提交,但是,TransactionScope 类没有规定回滚您的代码在事务本身范围之外所作的任何更改。如果在事务回滚时需要采取某项措施,必须自己编写 IEnlistmentNotification 接口的实现并显式在事务中登记。

示例

使用 System.Transactions 要求具有 System.Transactions.dll 的引用。

下面的函数演示如何针对包装在 TransactionScope 块中的两个不同 SQL Server 实例(由两个不同的 SqlConnection 对象表示)创建可提升事务。该代码使用 using 语句创建 TransactionScope 代码块并打开第一个连接,该连接自动在 TransactionScope 中登记。事务最初作为轻型事务登记,而不是作为完全分布式事务。仅当第一个连接中的命令没有引发异常时,才会在 TransactionScope 中登记第二个连接。打开第二个连接后,事务将自动提升为完全分布式事务。将会调用 Complete 方法,仅当未引发异常时,该方法才会提交事务。如果在 TransactionScope 代码块中的任意位置引发了异常,将不会调用 Complete,当在 TransactionScope 的 using 代码块结尾处执行 dispose 后,将回滚分布式事务。

 

原创粉丝点击