(精)C#中TransactionScope的使用方法和原理

标签:.net transactionscope
原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。http://cnn237111.blog.51cto.com/2359144/1271600

在.net 1.1的时代,还没有TransactionScope类,因此很多关于事务的处理,都交给了SqlTransaction和 SqlConnection,每个Transaction是基于每个Connection的。这种设计对于跨越多个程序集或者多个方法的事务行为来说,不 是非常好,需要把事务和数据库连接作为参数传入。

在.net 2.0后,TransactionScope类的出现,大大的简化了事务的设计。示例代码如下:

1
2
3
4
5
6
7
8
9
10
11
static void Main(string[] args)
        {
            using (TransactionScope ts = new TransactionScope())
            {
                userBLL u = new userBLL();
                TeacherBLL t = new TeacherBLL();
                u.ADD();
                t.ADD();
                ts.Complete();
            }
        }

只 需要把需要事务包裹的逻辑块写在using (TransactionScope ts = new TransactionScope())中就可以了。从这种写法可以看出,TransactionScope实现了IDispose接口。除非显示调用 ts.Complete()方法。否则,系统不会自动提交这个事务。如果在代码运行退出这个block后,还未调用Complete(),那么事务自动回 滚了。在这个事务块中,u.ADD()方法和t.ADD()方法内部都没有用到任何事务类。

TransactionScope是基于当前线程的,在当前线程中,调用Transaction.Current方法可以看到当前事务的信息。具体关于TransactionScope的使用方法,已经它的成员方法和属性,可以查看MSDN。

TransactionScope类是可以嵌套使用,如果要嵌套使用,需要在嵌套事务块中指定TransactionScopeOption参数。默认的这个参数为Required。

该参数的具体含义可以参考http://msdn.microsoft.com/zh-cn/library/system.transactions.transactionscopeoption(v=vs.80).aspx

比如下面代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
static void Main(string[] args)
        {
            using (TransactionScope ts = new TransactionScope())
            {
                Console.WriteLine(Transaction.Current.TransactionInformation.LocalIdentifier);
                userBLL u = new userBLL();
                TeacherBLL t = new TeacherBLL();
                u.ADD();
                using (TransactionScope ts2 = new TransactionScope(TransactionScopeOption.Required))
                {
                    Console.WriteLine(Transaction.Current.TransactionInformation.LocalIdentifier);
                    t.ADD();
                    ts2.Complete();
                }
               ts.Complete();
            }
        }

当嵌套类的TransactionScope的TransactionScopeOption为Required的时候,则可以看到如下结果,他们的事务的ID都是同一个。并且,只有当2个TransactionScope都complete的时候才能算真正成功。

ED8FDA3E241D48B0A90F30A5AC8A9A59

如果把TransactionScopeOption设为RequiresNew,则嵌套的事务块和外层的事务块各自独立,互不影响。

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
static void Main(string[] args)
        {
            using (TransactionScope ts = new TransactionScope())
            {
                Console.WriteLine(Transaction.Current.TransactionInformation.LocalIdentifier);
                userBLL u = new userBLL();
                TeacherBLL t = new TeacherBLL();
                u.ADD();
                using (TransactionScope ts2 = new TransactionScope(TransactionScopeOption.RequiresNew))
                {
                    Console.WriteLine(Transaction.Current.TransactionInformation.LocalIdentifier);
                    t.ADD();
                    ts2.Complete();
                }
              ts.Complete();
            }
        }

22D29B0134CD4993B629F085EEBF63D9

可以看到,他们的事务id是不一样的。

TransactionScopeOption设为Suppress则为取消当前区块的事务,一般很少使用。

对于多个不同服务器之间的数据库操作,TransactionScope依赖DTC(Distributed Transaction Coordinator)服务完成事务一致性。

但 是对于单一服务器数据,TransactionScope的机制则比较复杂。主要用的的是线程静态特性。线程静态特性 ThreadStaticAttribute让CLR知道,它标记的静态字段的存取是依赖当前线程,而独立于其他线程的。既然存储在线程静态字段中的数据 只对存储该数据的同一线程中所运行的代码可见,那么,可使用此类字段将其他数据从一个方法传递到该第一个方法所调用的其他方法,而且完全不用担心其他线程 会破坏它的工作。TransactionScope 会将当前的 Transaction 存储到线程静态字段中。当稍后实例化 SqlCommand 时(在此 TransactionScope 从线程局部存储中删除之前),该 SqlCommand 会检查线程静态字段以查找现有 Transaction,如果存在则列入该 Transaction 中。通过这种方式,TransactionScope 和 SqlCommand 能够协同工作,从而开发人员不必将 Transaction 显示传递给 SqlCommand 对象。实际上,TransactionScope 和 SqlCommand 所使用的机制非常复杂。具体可以参考文章http://www.microsoft.com/china/MSDN/library/netFramework/netframework/NETMattersSep.mspx?mfr=true

Wrox出版的《Professional C# 4 and .NET 4》也有关于TransactionScope的一些使用方法的介绍。

本文出自 “一只博客” 博客,请务必保留此出处http://cnn237111.blog.51cto.com/2359144/1271600

转载于:https://www.cnblogs.com/Impulse/articles/5263689.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/272224.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

一文搞定并发面试题

1、Object 的 wait()和notify() 方法下图为线程状态的图:Object 对象中的 wait()和notify()是用来实现实现等待 / 通知模式。其中等待状态和阻塞状态是不同的。等待状态的线程可以通过notify() 方法唤醒并继续执行,而阻塞状态的线程则是等待获取新的锁。…

阿里开源分布式事务seata带你入门

介绍 Seata 是阿里巴巴开源的分布式事务中间件,一种分布式事务解决方案,具有高性能和易于使用的微服务架构。 1:对业务无侵入:即减少技术架构上的微服务化所带来的分布式事务问题对业务的侵入 2:高性能:减少分布式事务解决方案…

jquery.validate.unobtrusive的使用

应用 一、引入 <script src"Scripts/jquery-1.7.1.min.js"></script> <script src"Scripts/jquery.validate.js"></script> <script src"Scripts/jquery.validate.unobtrusive.js"></script> 二、1&#xf…

Linux操作系统六大优点

❤️作者主页&#xff1a;IT技术分享社区 ❤️作者简介&#xff1a;大家好,我是IT技术分享社区的博主&#xff0c;从事C#、Java开发九年&#xff0c;对数据库、C#、Java、前端、运维、电脑技巧等经验丰富。 ❤️个人荣誉&#xff1a; 数据库领域优质创作者&#x1f3c6;&#x…

进程间通信IPC(一)(半双工管道和消息队列)

引言&#xff1a; 之前学习的进程之间交换信息的方法只能由fork或exec传送打开文件&#xff0c;或者文件系统。但是这种通讯方式有局限性&#xff0c;接下来将说明进程之间相互通信的其他技术——IPC(InterProcessCommunication)&#xff0c;过去UNIX系统IPC是各种进程间通信方…

Seata相关概念

相关概念 XID&#xff1a;一个全局事务的唯一标识 Transaction Coordinator (TC)&#xff1a; 事务协调器&#xff0c;维护全局事务的运行状态&#xff0c;负责协调并驱动全局事务的提交或回滚&#xff08;可以理解为事务的协调者&#xff09;。 Transaction Manager (TM)&…

Program terminated with signal SIGSEGV, Segmentation fault.

问题&#xff1a; 在程序运行时出现了&#xff1a;Segmentation fault (core dumped)&#xff0c;分段故障(堆芯转储)也就是段错误。 我首先在一篇博客上面找到如何使用gdb调试&#xff1a; 1、首先使用ulimit -a查看你的core file size是否为0.如果不是的话就请跳到步骤3&am…

NFS简介

NFS 是Network File System的缩写&#xff0c;即网络文件系统。一种使用于分散式文件系统的协定&#xff0c;由Sun公司开发&#xff0c;于1984年向外公布。功能是通过网络让不同的机器、不同的操作系统能够彼此分享个别的数据&#xff0c;让应用程序在客户端通过网络访问位于服…

Php Laravel框架 多表关系处理 之 Eloquent一对多关系处理

Php Laravel框架 多表关系处理 之 Eloquent一对多关系处理 本博文主要介绍 Laravel 框架中 Eloquent 对一对多关系的处理以及在 Laravel Administrator(后台扩展包)中的应用。 您的数据库可能是彼此相关的。比方&#xff0c;一篇博客文章可能有很多评论&#xff0c;或者一个订…

进程间通信IPC(二)(共享内存、信号、信号量)

共享内存&#xff1a; 共享内存就是允许两个或多个进程共享一定的存储区。就如同 malloc() 函数向不同进程返回了指向同一个物理内存区域的指针。当一个进程改变了这块地址中的内容的时候&#xff0c;其它进程都会察觉到这个更改。因为数据不需要在客户机和服务器端之间复制&am…

分布式理论CAP定理

CAP原则又称CAP定理&#xff0c;指的是在一个分布式系统中&#xff0c; Consistency&#xff08;一致性&#xff09;、 Availability&#xff08;可用性&#xff09;、Partition tolerance&#xff08;分区容错性&#xff09;&#xff0c;三者不可兼得。 998年&#xff0c;加州…

xmlWriter 以UTF-8格式写xml问题

dom4j中的XMLWriter提供以下几种构造方法&#xff1a; XMLWriter() XMLWriter(OutputFormat format) XMLWriter(OutputStream out) XMLWriter(OutputStream out, OutputFormat format) XMLWriter(Writer writer) XMLWriter(Writer writer, OutputFormat format) 最简单常…

linux线程(互斥锁、条件)

线程概念&#xff1a; 典型的UNIX/Linux进程可以看成只有一个控制线程&#xff1a;一个进程在同一时刻只做一件事情。有了多个控制线程后&#xff0c;在程序设计时可以把进程设计成在同一时刻做不止一件事&#xff0c;每个线程各自处理独立的任务。 进程是程序执行时的一个实例…

linux网络编程、socket编程

进程间通信&#xff1a; 特点&#xff1a;依赖于内核&#xff0c;造成缺陷——无法实现多机通信。 网络&#xff1a; 地址&#xff1a;由IP地址&#xff08;IP地址是IP协议提供的一种统一的地址格式&#xff0c;它为互联网上的每一个网络和每一台主机分配一个逻辑地址&#xf…

Linux文件和目录权限笔记

查看文件或者目录的权限命令&#xff1a;ls -al # -a 表示全部文件包含隐藏文件&#xff0c;-l 表示列出每个文件的详细信息比如执行 ls -altotal 115drwxr--x--- 4 root root 4096 Oct 24 02:07 install.log格式说明&#xff1a;通过 ls -al 格式化输出的文件详细信息&#x…

python基础:序列(列表、元组、字符串)、函数、字典、集合

Python语言运行环境&#xff1a; windowslinuxunixMacos等等 博客记录内容&#xff1a; Python3的所有语法、面向对象思维、运用模块进行编程、游戏编程、计算机仿真。 Python是什么类型的语言&#xff1a; Python是脚本语言&#xff0c;脚本语言(Scripting language)是电脑…