目录
1 为什么需要使用自动事务,使用自动事务有什么条件
2 什么是自动事务
3 自动事务在Web程序的使用的流程
3.1 注册组件
3.2 设计继承 ServicedComponent的类
4 部署分布式事务
1 为什么我们需要使用自动事务
在实际的软件开发过程中,一项功能对应了多个数据操作,这些数据操作是可以是单个数据源的操 作,也可以是多个数据源 的操作 ,这样通过手动设置事务将变成异常的复杂。在面对这样的问题下,我们可以通过自由事务,通过在Com+中注册的可以访问 Microsoft Transaction Server(MTS) 的Com+应用组件。我们可以不需要将一个功能的数个数据操作按个通过手动设置事务,并通过Try来捕捉异常来实现整体的事务。根据自定义服务组件类自定义事务,并设置事务的范围,在事务范围内发生异常,事务回滚,并抛出异常。下面我们具体的说明什么是自动事务.
2 什么是自动事务
下面就是MSDN中关于自动事务的解释
Microsoft 事务服务器 (MTS)、COM+ 和公共语言运行库都支持相同的自动分布式事务模型。
自动事务最大的特点就是自动的定义事务的边界,不需要显式的表示包含在事务中的动作
3自动事务在Web程序的使用的流程
自动事务在Web程序中使用 包含以下几个流程 注册组件,设计继承ServicedComponent的类,在程序中使用带有自动事物的类。
3.1 注册组件
在程序中包含自动事务的类在运行之前,我们需要将包含自动事务的组件在Com+中进行注册
这样对于需要注册的组件来讲就有两个要求
One 组件需要强名
Two 对组件进行注册
强名
组件的强命名是在组件编译时使用snk文件进行强命名,注意本组件引用的其他的组件必须也是强命名。
创建 snk文件
sn -k SnkFileName.snk
在项目的AssemblyInfo.cs文件中定义以下部分
[assembly: AssemblyKeyFile("snkFileName.snk")] //强名文件
[assembly: ApplicationName("ApplicationName")] //注册的程序名称
这样就能生成具有强名的应用程序
对组件进行注册
组件的注册是指将需要自动事务的组件注册到Com+中去
对组件的注册有两种方式
手动注册
手动注册是通过Regsvcs.exe程序进行服务组件的注册,
具体的流程是
打开Visual Studio .NET 2003 命令窗口
regsvcs /appname:myDllName mydllFileName.dll
myDllName : 注册的应用程序名称
mydllFileName.dll :需要注册的组件
注意 : 手动注册是将程序注册到全局缓存中
动态注册
在应用程序调用到自动事物的类的实例是,公共运行库将自动动态的注册组件,并配置Com+目录,这样的过程仅仅需要一次
在这里需要说明的是 ,在注册时需要有修改注册表和配置Com+目录的权限
对于Web系统来将 第一次我们需要在配置文件中加上
<identity impersonate="true" userName="Administrator" password="XXX "/>
进行标识 操作的系统用户
3.2设计继承 ServicedComponent的类
设计带有自动事务的类 包含两部分
继承ServicedComponent 类并标识事务属性
ServicedComponent 类是使用Com+服务的所有类的基类
事务的属性 说明如下:
特性值 |
说明 |
Disabled |
消除自动事务对对象的控制。应用此特性值的对象可以直接将分布式事务处理协调器 (DTC) 用于事务性支持。 [Transaction(TransactionOption.Disabled)] |
NotSupported |
指示对象不在事务范围内运行。处理请求后,不管是否有活动事务,均在没有事务的情况下创建其对象上下文。 [Transaction(TransactionOption.NotSupported)] |
Supported |
指示如果有事务,则对象在现有事务的上下文中运行。如果没有事务,则对象在没有事务的情况下运行。 [Transaction(TransactionOption.Supported)] |
Required (默认值) |
指示对象需要事务。如果有事务,则对象在现有事务范围中运行。如果没有事务,则对象启动一个事务。 [Transaction(TransactionOption.Required)] |
RequiresNew |
指示对象需要事务且为每个请求启动新事务。 [Transaction(TransactionOption.RequiresNew)] |
定义方法 并标识AutoComplete属性
(特别注意的是继承ServicedComponent 后 ,构造函数不能带参数 ,因为注册后 此类是一个公共的类)
实际在系统中应用的例子:
/// <summary>
/// 人员减少的基类
/// 包含人员在现职库的人员主键等属性
/// 人员减少的方法
/// 人员减少过程中的通用的功能
/// </summary>
[Transaction(TransactionOption.RequiresNew)]
public abstract class ReduceStaff:ServicedComponent
{
private string _staffID=string.Empty ;
private string _reduceExplain=string.Empty;
private string _reduceTime=string.Empty ;
private StaffReduceType _reduceType=StaffReduceType.其他 ;
private string _goToUnit=string.Empty ;
public ReduceStaff()
{
}
/// <summary>
/// 减少的人员对应的现职库的的ID标识
/// </summary>
public string StaffID
{
get{ return this._staffID ;}
set{this._staffID =value;}
}
/// <summary>
/// 人员减少的原因
/// </summary>
public string ReduceExplain
{
get{ return this._reduceExplain ;}
set{ this._reduceExplain =value;}
}
/// <summary>
/// 人员减少的时间
/// </summary>
public string ReduceTime
{
get{ return this._reduceTime ;}
set{ this._reduceTime =value;}
}
/// <summary>
/// 人员减少的原因类型
/// </summary>
public StaffReduceType ReduceType
{