事务基础详解
来源:互联网 发布:程序员对笔记本尺寸 编辑:程序博客网 时间:2024/06/08 04:09
一、事务的定义
所谓事务,它是一个操作集合,这些操作要么都执行,要么都不执行,它是一个不可分割的工作单位。典型的例子就像从网上银行系统的帐户A转帐到帐户B,它经过两个阶段:1.从帐户A取出款项。2.把款项放入帐户B中。这两个过程要么同时成功,要么同时失败,这一系列的操作就被称为事务性(Transactional)操作。
在一个事务性操作的环境下,操作有着以下的4种特性,被称为ACID特性
原子性(Atomicity)当事务结束,它对所有资源状态的改变都被视为一个操作,这些操作要不同时成功,要不同时失败 一致性(Consistency)操作完成后,所有数据必须符合业务规则,否则事务必须中止隔离性(Isolation)事务以相互隔离的方式执行,事务以外的实体无法知道事务过程中的中间状态持久性(Durable)事务提交后,数据必须以一种持久性方式存储起来
二、事务管理器
在软件系统当中可以看到无论在数据库、Web服务、WCF、文件系统都存在着数据参与到事务运作当中,我们把管理这些数据的工具称为资源管理器RM(Resources Manager)。而事务管理器TM(Transaction Manager)就是协调多个资源管理器的工作,保证数据完整性的工具。
由上图可以看到事务的管理流程,系统通知事务管理器TM来启动事务,事务管理器TM控制向多个资源管理器RM并协调RM之间的事务操作。图中存在两个持久化RM,分别管理数据库和文件系统,这些事务操作要不同时成功,要不同时失败。
事务管理器一般分为三类:轻量级事务管理器(LTM)、核心事务管理器(KTM)、分布式事务协调器(DTC)
1. 轻量级事务管理器 (LTM)
它是包括在System.Transactions 命名空间内的一个事务管理框架,它只能管理单个应用程序域内的事务。LTM 可以管理多个易变的RM,但只能管理一个持久化RM。若事务试图加入第二个持久化RM,那轻量级事务管理器LTM将提升级别。LTM是性能最高的事务管理器,在可选择的情况下应该尽可能地使用 LTM 事务管理器。
这里易变RM是指它参与会引发 “未确定状态” 的2PC事务时候,不需要恢复服务,更多时候,易变RM的数据只存储在内存当中。
而持久化RM是指它参与会引发 “未确定状态” 的2PC事务时候,它需要恢复服务,持久化RM管理的数据是在于硬盘当中。所以,参与2PC事务的的持久RM必须有新旧两个版本,如果事务引发 “未确定状态” 的时候,那么它就会联系持久化RM,恢复到其中一个版本。
- 2PC说明 (http://blogs.msdn.com/b/diegumzone/archive/2006/08/14/699219.aspx)
2PC 是2 Phase Commit的缩写,代表事务的2阶段提交验证算法:在数据提交时,第一阶段:应用程序记录每个数据源并执行更新请求,TM通知每个RM来执行分布式事 务,然后每个RM都对数据执行本地的事务,在事务将提交前,TM会与各个RM进行信息交换,以获知更新是否成功。第二阶段,如果其中任何一个RM表示更新 失败,TM就会通知所有的RM事务操作失败,实现数据回滚。如果所有RM的操作都成功,那么整个TM事务就宣告成功。
2. 核心事务管理器 (KTM)
KTM是用于Windows Vista和Windows Server 2008 系统中的轻量级事务管理器,与LTM相像,它可以管理多个易变的RM,但只能管理一个持久化RM。
3. 分布式事务协调器(DTC)
分布式事务协调器DTC(Distributed Transaction Coordinator)能管理多个持久化RM中的事务,事务可以跨越应用程序域、进程、硬件、域等所有的边界。在Windows Server 2008当中,DTC支持OleDB、XA、WS-AtomicTransaction、WSCoordination、WS-BusinessActivity等多个协议。由于分布式事务需要在多个参与方之间实现多次通讯,所以是一种巨大的开销,因此,在可以使用LTM和KTM的时候,应该尽量避免使用DTC。在上面图片中的事务同时启动了两个RM分别处理数据库数据与文件数据,当中启动的就是DTC分布式事务。
4.事务类 System.Transactioins.Transaction
Transaction是由Framework 2.0 就开始引入,用于显示管理事务的一个类。通过Transaction可以直接管理事务的中止、释放,也可以获取、克隆当前的环境事务类。
- Transaction的公用属性
其中Transaction.Current 比较常用,它可以指向一个当前运行环境中的事务,如果环境事务不存在,系统将返回一个null
Transaction transaction=Transaction.Current;
- Transaction的常用公用方法
其中Rollback、Dispose方法可以控制事务中止、释放,而Clone、DependentClone方法在多线程操作中经常用到,在 “异步事务” 一节中将详细说明
- Transaction的事件
在事务完成后,会触发TransactionCompleted事件,开发人员可以在此事件的过程监测其状态
5. 事务状态 TransactionInformation
上面讲解过事务分为本地事务与分布式事务,而Transaction类的TransactionInformation是事务状态的记录,它可以跟踪事务动作,分辨事务现处的状态,记录本地事务与分布式事务的Guid。
TransactionInformation有两个重要成员
1 public class TransactionInformation
2 {
3 //返回分布式事务标识符
4 public Guid DistributedIdentifier
5 {get;}
6
7 //返回本地事务标识符
8 public string LocalIdentifier
9 {get;}
10 }
LocalIndentifier是本地事务的标识符,它可以获取本地事务管理器(LTM)的ID,并且注意只要事务存在,它的值就永远不会是null。它包含两个部分,一个是LTM的Guid,它是应用程序中的唯一值,代表了现存应用程序域分配的LTM。另一部分是一个可变量,代表了当时该应用程序域中的事务数量。
例如:3427dec9-4abc-34cc-9edf-30ad835c33k3:3
其中3427dec9-4abc-34cc-9edf-30ad835c33k3是此本地事务管理器的Guid,在事务启动后,此值都是不变的,而 “3” 代表此刻该应用程序域中存在 “3” 个本地事务。
DistributedIndentifier是分布式事务的标识符,在普通情况下DistributedIndentifier的值都为Guid.Empty。但当LTM或KTM事务被提升到分布式事务时,DistributedIndentifier就会产生。最重的是,在同一个分布式事务管理器当中,即使事务跨越服务边界,分布式ID都是一致的。DistributedIndentifier是分布式事务的唯一标识符,它的使用方法在后面 “事务的传播” 一节将详细介绍。
在TransactionManager类中,还提供了一个事件DistributedTransactionStarted专门用于测试分布式事务的变化。
1 class Program
2 {
3 static void Main(string[] args)
4 {
5 using (TransactionScope scope = new TransactionScope())
6 {
7 TransactionManager.DistributedTransactionStarted += OnDistributedTransactionStarted;
8 ............
9 scope.Complete();
10 }
11 Console.ReadKey();
12 }
13
14 //当执行分布式事务是就会启动此方法显示事务信息
15 static void OnDistributedTransactionStarted(object sender, TransactionEventArgs args)
16 {
17 Transaction transaction = args.Transaction;
18 Console.WriteLine("Distributed Transaction Started!\n DistributedIndentifier:"
19 +transaction.TransactionInformation.DistributedIdentifier);
20 }
21 }
- 事务基础详解
- 【spring基础】spring声明式事务详解
- 事务基础
- spring(基础七) spring事务回滚详解
- redis处理事务和memcache缓存基础的详解
- 事务详解
- 事务详解
- 事务详解
- 事务详解
- 事务详解
- 事务详解
- 事务详解
- 事务详解
- 事务详解
- Spring详解-----------事务详解
- Spring详解-----------事务详解
- 【词汇详解】事务详解
- 事务基础(1)
- LeetCode 52 N-Queens II
- 自定义Toast实现多次触发只显示一次toast使用改良
- mybatis trim标签用法
- lintcode(184)最大数
- 刷清橙OJ--A1034.孪生素数对
- 事务基础详解
- Ajax的错误调试
- 第3章 编程问题 3.3节 9
- Android之SharedPreferences详解
- 双卡时候获取指定的imsi码
- [一天几个linux命令] cd
- 交叉编译安装ARM平台上的Qt
- 【前端技巧】html右键禁用和web页面中添加加入qq群的方式
- Java环境搭建一JDK安装下载配置