浅谈事务、COM+及分布式事务

来源:互联网 发布:国家大数据平台登录 编辑:程序博客网 时间:2024/04/29 04:08

浅谈事务、COM+及分布式事务

 

目录

1     什么是事务及特性...................................................................................................................................... 2

1.1       什么是事务:......................................................................................................................................... 2

1.2       事务的特性(ACID原则):.............................................................................................................. 2

1.2.1       原子性(ATOMICITY).............................................................................................................. 2

1.2.2       一致性(CONSISTENCY)........................................................................................................ 3

1.2.3       隔离性(ISOLATION)............................................................................................................... 3

1.2.4       持久性(DURABILITY)............................................................................................................. 3

2     事务应用的范围........................................................................................................................................... 3

3     数据库中事务处理...................................................................................................................................... 3

3.1       事务工作原理......................................................................................................................................... 4

3.2       空间管理................................................................................................................................................. 5

3.2.1       行级锁............................................................................................................................................ 6

3.2.2       页级锁............................................................................................................................................ 6

3.2.3       簇级锁............................................................................................................................................ 7

3.2.4       表级锁............................................................................................................................................ 8

3.2.5       数据库级锁................................................................................................................................... 8

3.3       死锁问题................................................................................................................................................. 9

3.4       事务模式............................................................................................................................................... 10

3.4.1       自动提交事务模式.................................................................................................................... 10

3.4.1.1      编译时错误的处理................................................................................................................... 10

3.4.1.2      运行时错误的处理................................................................................................................... 10

3.4.2       隐式提交事务模式.................................................................................................................... 11

3.4.3       显示提交事务模式.................................................................................................................... 12

3.5       事务中不支持的SQL语句................................................................................................................ 12

4     什么叫分布式事务.................................................................................................................................... 13

5     COM+简单介绍.......................................................................................................................................... 13

5.1       组件(Component)和对象(Object)之间的区别.............................................................. 13

5.2       ActiveXOLECOM的关系..................................................................................................... 13

5.3       COMMTSCOM+....................................................................................................................... 15

5.3.1    DCOM............................................................................................................................................... 15

5.3.2    MTS................................................................................................................................................... 15

5.3.3    COM+的出现.................................................................................................................................. 15

6     COM+与分布式事务................................................................................................................................. 16

6.1       Transaction Support所支持的属性:..................................................................................... 17

6.2       活动与同步........................................................................................................................................... 17

6.3       事务的生存期....................................................................................................................................... 18

6.3.1       事务开始..................................................................................................................................... 19

6.3.2       建立与resource manager的连接.......................................................................................... 19

6.3.3       执行操作..................................................................................................................................... 20

6.3.4       表决事务的结果........................................................................................................................ 21

6.4       事务生存期小结.................................................................................................................................. 22

7     .NET中开发COM+实现分布事务................................................................................................... 22

7.1       开发事务型COM+组件..................................................................................................................... 22

7.2       COM+类示例........................................................................................................................................ 23

7.3       利用TransactionScope类实现分布式事务............................................................................. 25

7.4       SQLServer2000中实现分布式事务.......................................................................................... 25

7.4.1       访问格式:................................................................................................................................. 26

7.4.2       示例:.......................................................................................................................................... 26

8     .NET开发COM+注意事项...................................................................................................................... 26

9     配置与部署COM+..................................................................................................................................... 27

9.1       配置MSDTC........................................................................................................................................ 27

9.2       打开双方135端口............................................................................................................................... 28

9.3       注册COM+服务.................................................................................................................................. 28

10       开发中碰到的错误及处理办法........................................................................................................ 28

1       什么是事务及特性

1.1        什么是事务:

简单的说,事务就是用户定义的一个操作序列(简单的说就是一条或多条数据执行语句,或者是其它的操作)的组合,如果其中的任一操作执行失败,则所有的操作都应撤销,还原到没有操作之前的状态,也就是说,操作序列中的操作要么都成功,要么都失败,是一个整体。

1.2        事务的特性(ACID原则):

事务必须要满足原子性、一致性、隔离性和持久性等四个特点,才能算是一个事务

1.2.1   原子性(ATOMICITY)

原子性用于标识事务是否完全地完成,一个事务的任何更新要在系统上完全完成,在任何操作出现一个错误的情况下,构成事务的所有操作的效果必须被撤消,数据应被回滚到操作前的状态。也就是说,一个事务要被完全的无二义性的做完或撤消。

1.2.2   一致性(CONSISTENCY)

一致性保证任何事务最后都处于有效状态,一个事务应该保护所有定义在数据上的不变的属性(例如完整性约束)。在完成了一个成功的事务时,数据应处于一致的状态。换句话说,一个事务应该把系统从一个一致状态转换到另一个一致状态。

1.2.3   隔离性(ISOLATION)

隔离性确保每一事务在系统中认为只有该事务在使用系统资源,在同一个环境中可能有多个事务并发执行和用到相同资源,这种属性有时称为串行化,也就是说,事务会独占相关资源,直到整个事务完成,在资源被占用期间,其它事务不能使用相关资源,直到被当前事务完成(数据库管理系统通常使用锁来实现)。在一个事务执行过程中,数据的中间的(可能不一致)状态不应该被暴露给所有的其他事务。

1.2.4   持久性(DURABILITY)

持久性确保事务的变化是永久性的,持久性意味着一旦事务执行成功,在系统中产生的所有变化将是永久的。

2       事务应用的范围

只要在一次功能执行中,涉及到对多个资源进行操作(如对数据的增加、修改、删除)的情况,都需要应用事务。事务不仅是只存在于数据库中,在其它应用中,它无处不在,如 银行、证券交易系统;

3       数据库中事务处理

为了实现事务,数据库中引入了锁的机制。数据库中有多种锁,允许事务锁定不同的资源。锁就是保护指定的资源,在同一时间不被其他事务操作。为了最小化锁的成本,SQL Server自动地以与任务相应等级的锁来锁定资源对象。锁定比较小的对象,例如锁定行,虽然可以提高并发性,但是却有较高的开支,因为如果锁定许多行,那么需要占有更多的锁;锁定比较大的对象,例如锁定表,会大大降低并发性,因为锁定整个表就限制了其他事务访问该表的其他部分,但是成本开支比较低,因为只需维护比较少的锁。

锁具有如下特点:

l         锁是保证并发控制的手段

l         可以锁定的资源包括行、页、簇、表和数据库

l         锁类型主要包括共享锁和排它锁,特殊类型的锁包括意图锁、修改锁和模式锁

l         共享锁允许其他事务继续使用锁定的资源,排它锁只允许一个事务访问数据

l         系统本身可以处理死锁

l         用户可以根据实际情况定制锁的一些特征

使用事务时,原则上应该使事务尽可能的短并且要避免事务嵌套。

3.1        事务工作原理

事务确保数据的一致性和可恢复性。事务的工作原理如图1所示,事务开始之后,事务所有的操作都陆续写到事务日志中。写到日志中的操作,一般有两种:一种是针对数据的操作,一种是针对任务的操作。

针对数据的操作,例如插入、删除和修改,这是典型的事务操作,这些操作的对象是大量的数据;针对任务的操作,例如创建索引,增加字段,这些任务操作在事务日志中记录一个标志,用于表示执行了这种操作,当取消这种事务时,系统自动执行这种操作的反操作,保证系统的一致性。

系统自动生成一个检查点机制,这个检查点周期地发生。检查点的周期是系统根据用户定义的时间间隔和系统活动的频度由系统自动计算出来的时间间隔。检查点周期地检查事务日志,如果在事务日志中,事务全部完成,那么检查点将事务日志中的事务提交到数据库中,并且在事务日志中做一个检查点提交标记。如果在事务日志中,事务没有完成,那么检查点将事务日志中的事务不提交到数据库中,并且在事务日志中做一个检查点未提交标记。

继续执行

事务开始

事务的每步操作写到日志中

检查点机制检查

事务是否完成

事务写到日志中

成功

文本框: 失败

事务工作原理图(1)

 

事务的恢复以及检查点保护系统的完整和可恢复,可以使用如图2所示的示例说明。

 

事务恢复和检查点示例图(图2

在这个示例图中,有五个事务:事务1、事务2、事务3、事务4和事务5。方框表示事务的开始和完成提交。水平方向表示时间。检查点表示在某一时间点发生检查点机制,系统失败表示在某一时间点由于断电、系统软件失败等原因而发生的系统失败。事务1的完成发生在检查点发生之间,所以事务1被提交到数据库中。事务2和事务4的完成发生在系统失败之前,所以这两个事务可以被系统向前滚动提交到数据库中。事务3和事务5由于系统失败而没有完成,所以这两个事务被取消。

3.2        空间管理

锁是防止其他事务访问指定的资源控制、实现并发控制的一种主要手段。为了提高系统的性能,加快事务的处理速度,缩短事务的等待时间,应该使锁定的资源最小化。为了控制锁定的资源,应该首先了解系统的空间管理。

页:在SQL Server系统中,最小的空间管理单位是页,一个页有8K。所有的数据、日志、索引都存放在页上。另外,使用页有一个限制,这就是表中的一行数据必须在同一个页上,不能跨页(因此,我们在定义表结构时,所有字段所占空间之和不能超过8K的原因)。

簇:页上面的空间管理单位是簇,一个簇是8个连续的页。

表和索引:表和索引的最小占用单位是簇。

数据库:数据库是由一个或者多个表或者索引组成,即是由多个簇组成。

SQL Server系统的空间管理结构示意图如图3所示。

 

 

 

 

 

 

 

 

 

SQL Server空间管理(图3

3.2.1   行级锁

行是可以锁定的最小空间。在SQL Server 7.0中,实现了行级锁。行级锁就是指事务在操纵数据的过程中,锁定一行或者若干行数据,其他事务不能同时处理这些行的数据。行级锁占用的数据资源最少,所以在事务的处理过程中,允许其他事务继续操纵同一个表或者同一个页的其他数据,大大降低了其他事务等待处理的时间,提高了系统的并发性。行级锁是一种最优锁,因为行级锁不可能出现数据既被占用又没有使用的浪费现象。在图4中,椭圆形表示行级锁占用的数据,而椭圆形之外的其他数据仍然可以由其他事务使用。行级锁是SQL Server 7.0的重要特征,它的引入引起了数据存储引擎的改变。

行级锁(图4

3.2.2   页级锁

页级锁是指在事务的操纵过程中,无论事务处理数据的多少,每一次都锁定一页,在这个页上的数据不能被其他事务操纵。在SQL Server 7.0以前,使用的是页级锁。页级锁锁定的资源比行级锁锁定的数据资源多。在页级锁中,即使是一个事务只操纵页上的一行数据,那么该页上的其他数据行也不能被其他事务使用。因此,当使用页级锁时,会出现数据的浪费现象,也就是说,在同一个页上会出现数据被占用却没有使用的现象。在这种现象中,数据的浪费最多不超过一个页上的数据行。在图5中,圆形区表示一个页级锁,在这个圆形区内,只有一个事务可以可以使用圆形区中的数据,其他事务只能使用圆形区以外的数据。

页级锁(图5

3.2.3   簇级锁

簇级锁是一种特殊类型的锁,只能用在一些特殊的情况下。簇级锁就是指事务占用一个簇,这个簇不能同时被其他事务占用。例如在创建数据库和创建表时,系统分配物理空间时使用这种类型的锁。系统是按照簇分配空间的。当系统分配空间时,使用簇级锁,防止其他事务同时使用同一个簇。当系统完成分配空间之后,就不再使用这种类型的簇级锁。特别是,当涉及到对数据操作的事务时,不使用簇级锁。簇级锁的结构如图6所示。椭圆形区域表示簇级锁占用的数据,其他事务只能使用该簇以外的其他簇。

簇级锁(图6

3.2.4   表级锁

表级锁也是一个非常重要的锁。表级锁是指事务在操纵某一个表的数据时,锁定了这个数据所在的整个表,其他事务不能访问该表中的其他数据。当事务处理的数据量比较大时,一般使用表级锁。表级锁的特点是使用比较少的系统资源,但是却占用比较多的数据资源。与行级锁和页级锁相比,表级锁占用的系统资源例如内存比较少,但是占用的数据资源却是最大。在表级锁时,有可能出现数据的大量浪费现象,因为表级锁锁定整个表,那么其他的事务都不能操纵表中的其他数据。这样,会延长其他事务等待处理的时间,降低系统的并发性能。表级锁的结构示意图如图8所示,椭圆形表示表级锁。

表级锁(图7

3.2.5   数据库级锁

数据库级锁是指锁定整个数据库,防止任何用户或者事务对锁定的数据库进行访问。数据库级锁是一种非常特殊的锁,它只是用于数据库的恢复操作过程中。这种等级的锁是一种最高等级的锁,因为它控制整个数据库的操作。只要对数据库进行恢复操作,那么就需要设置数据库为单用户模式,这样系统就能防止其他用户对该数据库进行各种操作。数据库级锁的结构示意图如图8所示。严格地说,数据库级锁不是一种锁,而是一种类似锁的一种单用户模式机制。但是,这种单用户模式机制非常类似锁机制,因此也可以把这种单用户模式称为数据库级锁。

数据库锁(图8

3.3        死锁问题

死锁是一个很重要的话题。在事务和锁的使用过程中,死锁是一个不可避免的现象。在两种情况下,可以发生死锁。

第一种情况是,当两个事务分别锁定了两个单独的对象,这时每一个事务都要求在另外一个事务锁定的对象上获得一个锁,因此每一个事务都必须等待另外一个事务释放占有的锁,这时,就发生了死锁。这种死锁是最典型的死锁形式。在同一时间内有两个事务AB,事务A有两个操作:锁定表part和请求访问表supplier;事务B也有两个操作:锁定表supplier和请求访问表part。结果,事务A和事务B之间发生了死锁,其示意进程如图9所示。

死锁示意图(图9

死锁的第二种情况是,当在一个数据库中时,有若干个长时间运行的事务执行并行的操作,当查询分析器处理一种非常复杂的查询例如连接查询时,那么由于不能控制处理的顺序,有可能发生死锁现象。

当发生死锁现象时,系统可以自动检测到,然后通过自动取消其中一个事务来结束死锁。在发生死锁的两个事务中,根据事务处理时间的长短作为规则来确定他们的优先级。处理时间长的事务具有较高的优先级,处理时间较短的事务具有较低的优先级。在发生冲突时,保留优先级高的事务,取消优先级低的事务。

3.4        事务模式

SQL Server中,有三种事务模式:自动提交模式、隐性提交模和显式提交模,自动提交模式是SQL Server 的默认事务管理模式

3.4.1   自动提交事务模式

这是 SQL Server 的默认模式。每个单独的 SQL 语句都在其完成后提交,不需指定任何语句控制事务。如果在自动提交模式中的最后调用 commit,则会出错。

3.4.1.1             编译时错误的处理

如果在一个批处理的SQL语句中(以GO分隔的一批语句就叫批处理SQL语句),有一个SQL语句有语法错误,则整个批处理不会被执行,这是因为编译错误将阻止 SQL Server 建立执行计划,所以批处理中的任何语句都没有执行,而不是因为执行了批处理又回滚整个批处理的情况。

在如下示例中,由于编译时错误,第三个批处理中的任何 INSERT 语句都没有执行。但看上去好像是前两个 INSERT 语句执行了又被回滚:

USE pubs

GO

CREATE TABLE TestTable (Field1 INT, Field2 VARCHAR(10))

GO

INSERT INTO TestTable VALUES (1, 'aaa')

INSERT INTO TestTable VALUES (2, 'bbb')

INSERT INTO TestTable VALUSE (3, 'ccc')  -- 有语法错误

GO

SELECT * FROM TestTable -- 返回空行

GO

3.4.1.2             运行时错误的处理

运行时错误指的是在执行过程中产生的错误,对插入数据时键重复、对象不存在等,在下面的示例中,第三个 INSERT 语句产生运行时重复键错误。由于前两个 INSERT 语句成功地执行并且提交,因此它们在运行时错误之后被保留下来:

USE pubs

GO

CREATE TABLE TestTable (Field1 INT PRIMARY KEY, Field2 CHAR(10))

GO

INSERT INTO TestTable VALUES (1, 'aaa')

INSERT INTO TestTable VALUES (2, 'bbb')

INSERT INTO TestTable VALUES (1, 'ccc')  -- 运行时产生主键重复错误

GO

SELECT * FROM TestTable  -- 返回插入的前二行数据

GO

由于SQL Server 使用延迟的名称解析,其中对象名直到执行时才被解析,下面的示例在语法上通过,但在执行时在下面的示例中,前两个 INSERT 语句执行并提交,当第三个 INSERT 语句由于引用了一个并不存在的表而产生运行时错误之后,前两行将仍然保留在 TestTable表中:

USE pubs

GO

CREATE TABLE TestTable (Field1 INT PRIMARY KEY, Field2 CHAR(10))

GO

INSERT INTO TestTable VALUES (1, 'aaa')

INSERT INTO TestTable VALUES (2, 'bbb')

INSERT INTO TestTabl VALUES (3, 'ccc')  -- 表名少了一个字母e,表不存在

GO

SELECT * FROM TestTable -- 返回前二行数据

GO

3.4.2   隐式提交事务模式

通过SET IMPLICIT_TRANSACTIONS ON 语句,将隐性事务模式设置为打开,从此语句的下一个语句开始处,自动启动一个新事务,直到调用了 COMMITROLLBACK语句或SET IMPLICIT_TRANSACTIONS OFF时,该事务完成。如果是在语句块的中间调用了COMMIT语句,则COMMIT语句的下一个 SQL 语句又将启动一个新事务,如此规律执行。

下面的示例中,第三个批处理语句开启隐性事务模式,第四个批处理语句块在最后处调用 COMMIT提交,随后在第五个批处理语句块中,回滚隐性事务,第六个批处理语句插入数据,但没有显示调用COMMIT

USE pubs

GO

CREATE TABLE TestTable (Field1 INT PRIMARY KEY, Field2 CHAR(10))

GO

SET IMPLICIT_TRANSACTIONS ON -- 将隐性事务模式设置为打开

GO

INSERT INTO TestTable VALUES (1, 'aaa') -- 在此句处自动启动一个新事务

INSERT INTO TestTable VALUES (2, 'bbb') -- 包含在上面语句启动的事务范围内

COMMIT -- 在此调用事务提交语句,完成并结束开启的隐性事务

GO

INSERT INTO TestTable VALUES (3, 'ccc') -- 此句处又自动启动一个新事务

ROLLBACK -- 回滚隐性事务,上面的插入语句失效

GO

INSERT INTO TestTable VALUES (4, 'ddd')) -- 此句处再次自动启动一个新事务

GO

 

SELECT * FROM TestTable 当前返回124数据

GO

对于通过设置了隐性事务为ON 而自动打开的事务,用户必须在该事务结束时将其显式提交或回滚。否则当用户断开连接时,事务及其所包含的所有数据更改将回滚。

对于上面的执行结果,如果重新连接数据库执行SELECT * FROM TestTable 语句,则返回的结果是12数据。说明上面的示例在断开后,自动回滚了最后自动开启的隐性事务。

3.4.3   显示提交事务模式

通过发出 BEGIN TRANSACTION 语句显式启动事务。从该语句开始处,下面的所有语句都在一个事务中,直到碰到了COMMITROLLBACK语句。显式事务模式持续的时间只限于该事务的持续期,当事务结束时,连接将返回到启动显式事务前所处的事务模式,或者是隐性模式,或者是自动提交模式。

USE pubs

GO

BEGIN TRAN -- 显示开启事务

CREATE TABLE TestTable (Field1 INT PRIMARY KEY, Field2 CHAR(10))

GO

INSERT INTO TestTable VALUES (1, 'aaa')

INSERT INTO TestTable VALUES (2, 'bbb')

INSERT INTO TestTable VALUES (3, 'ccc') 

GO

SELECT * FROM TestTable 在事务内执行,将返回123数据

GO

ROLLBACK TRAN 回滚显示事务,事务内所有的操作都被回滚,包括创建表

GO

SELECT * FROM TestTable 此句执行时错误,因为库中不存在表

GO

3.5        事务中不支持的SQL语句

在事务中,不支持对数据库、日志、配置等操作的SQL语句。

SQL语句

功能

ALTER DATABASE

修改数据库

BACKUP LOG

备份日志

CREATE DATABASE

创建数据库

DISK INIT

创建数据库或事务日志设备

DROP DATABASE

删除数据库

DUMP TRANSACTION

转储事务日志

LOAD DATABASE

装载数据库备份复本

LOAD TRANSACTION

装载事务日志备份复本

RECONFIGURE

更新使用 sp_configure 系统存储过程更改的配置选项的当前配置(sp_configure 结果集中的 config_value 列)值

RESTORE DATABASE

还原使用BACKUP命令所作的数据库备份

RESTORE LOG

还原使用BACKUP命令所作的日志备份

UPDATE STATISTICS

在指定的表或索引视图中,对一个或多个统计组(集合)有关键值分发的信息进行更新

SP_DBOPTION

设置数据库选项

事务保存点,嵌套事务

4       什么叫分布式事务

要了解分布式事务,要先了解什么是分布式数据库系统,分布式数据库系统:指在物理上分散而逻辑上集中的数据库系统。其特点是:

l         物理分布性,数据不在单个站点上, 按全局需求将数据划分成一定的数据子集,分散存储在各个站点上;

l         逻辑整体性,各个站点上的数据子集, 相互间有严密的约束规则加以限定, 逻辑上是一个整体;

l         站点自治性,各个站点上的数据(LDB)是有本地的DBMS管理, 具有自治处理能力。

分布式事务,就是在一个完整操作中,

5       COM+简单介绍

5.1        组件(Component)和对象(Object)之间的区别

在了解COM相关知识之间,先了解组件与对象之间的区别。组件是一个可重用的模块,它是由一组处理过程、数据封装和用户接口组成的业务对象(Rules Object)。组件看起来像对象,但不符合对象的学术定义。它们的主要区别是:

l         组件可以在另一个称为容器(有时也称为承载者或宿主)的应用程序中使用,也可以作为独立过程使用;

l         组件可以由一个类构成,也可以由多个类组成,或者是一个完整的应用程序;

l         组件为模块重用,而对象为代码重用。

5.2        ActiveXOLECOM的关系

大家或多或少都应该听说过ActiveXOLECOM/DCOM这些概念,但是他们之间是什么样的关系,可能并不完全清楚。

从时间的角度讲,OLE是最早出现的,然后是COMActiveX;从体系结构角度讲,OLEActiveX是建立在COM之上的,所以COM是基础;单从名称角度讲,OLEActiveX是两个商标名称,而COM则是一个纯技术名词,这也是大家更多的听说ActiveXOLE的原因。

既然OLE是最早出现的,那么就从OLE说起,自从Windows操作系统流行以来,“剪贴板”(Clipboard)首先解决了不同程序间的通信问题(由剪贴板作为数据交换中心,进行复制、粘贴的操作),但是剪贴板传递的都是“死”数据,应用程序开发者得自行编写、解析数据格式的代码,于是动态数据交换(Dynamic Data ExchangeDDE)的通信协定应运而生,它可以让应用程序之间自动获取彼此的最新数据,但是,解决彼此之间的“数据格式”转换仍然是程序员沉重的负担。对象的链接与嵌入(Object Linking and EmbeddedOLE)的诞生把原来应用程序的数据交换提高到“对象交换”,这样程序间不但获得数据也同样获得彼此的应用程序对象,并且可以直接使用彼此的数据内容,其实OLEMicrosoft的复合文档技术,它的最初版本只是瞄准复合文档,但在后续版本OLE2中,导入了COM。由此可见,COM是应OLE的需求而诞生的,所以虽然COMOLE的基础,但OLE的产生却在COM之前。

COM的基本出发点是,让某个软件通过一个通用的机构为另一个软件提供服务。COM是应OLE的需求而诞生,但它的第一个使用者却是OLE2,所以COM与复合文档间并没有多大的关系,实际上,后来COM就作为与复合文档完全无关的技术,开始被广泛应用。这样一来,Microsoft就开始“染指”通用平台技术。但是COM并不是产品,它需要一个商标名称。而那时Microsoft的市场专家们已经选用了OLE作为商标名称,所以使用COM技术的都开始贴上了OLE的标签。虽然这些技术中的绝大多数与复合文档没有关系。Microsoft的这一做法让人产生这样一个误解OLE是仅指复合文档呢?还是不单单指复合文档?其实OLECOM的商标名称,自然不仅仅指复合文档。但Microsoft自己恐怕无法解释清楚,这要花费相当的精力和时间。

于是,随着Internet的发展,在1996年春,Microsoft改变了主意,选择ActiveX作为新的商标名称。ActiveX是指宽松定义的、基于COM的技术集合,而OLE仍然仅指复合文档。当然,ActiveX最核心的技术还是COMActiveXOLE的最大不同在于,OLE针对的是桌面上应用软件和文件之间的集成,而ActiveX则以提供进一步的网络应用与用户交互为主。到这里,大家应该对ActiveXOLECOM三者的关系有了一个比较明确的认识,COM才是最根本的核心技术,所以下面的重点COM

让对象模型完全独立于编程语言,这是一个非常新奇的思想。这一点从C++Java的对象概念上,我们就能有所了解。但所谓COM对象究竟是什么呢?为了便于理解,可以把COM看作是某种(软件)打包技术,即把它看作是软件的不同部分,按照一定的面向对象的形式,组合成可以交互的过程和以组支持库。COM对象可以用C++JavaVB等任意一种语言编写,并可以用DLL或作为不同过程工作的执行文件的形式来实现。使用COM对象的浏览器,无需关心对象是用什么语言写的,也无须关心它是以DLL还是以另外的过程来执行的。从浏览器端看,无任何区别。这样一个通用的处理技巧非常有用。例如,由用户协调运行的两个应用,可以将它们的共同作业部分作为COM对象间的交互来实现(当然,现在的OLE复合文档也能做到)。为在浏览器中执行从Web服务器下载的代码,浏览器可把它看作是COM对象,也就是说,COM技术也是一种打包可下载代码的标准方法(ActiveX控件就是执行这种功能的)。甚至连应用与本机OS进行交互的方法也可以用COM来指定,例如在WindowsWindows NT中用的是新API,多数是作为COM对象来定义的。可见,COM虽然起源于复合文档,但却可有效地适用于许多软件问题,它毕竟是处在底层的基础技术。用一句话来说,COM是独立于语言的组件体系结构,可以让组件间相互通信。随着计算机网络的发展,COM进一步发展为分布式组件对象模型,这就是DCOM,它类似于CORBAORB,也及现在要关注的COM+技术。

5.3        COMMTSCOM+

5.3.1   DCOM

COM+出现之前,还出现了DCOMMTS技术。DCOM(分布式组件对象模型)是一系列微软的概念和程序接口,利用这个接口,客户端程序对象能够请求来自网络中另一台计算机上的服务器程序对象。DCOM基于组件对象模型(COM)。使用DCOM接口,网络服务器站点程序(现在以客户端对象方式发出动作)就能够将一个远程程序调用(RPC)发送到一个专门的服务器对象,它可以通过必要的处理,并给站点返回一个结果。结果将发送到网页浏览器上。

DCOM还可以工作在位于企业内部或者除了公共因特网之外的其他网络中。它使用TCP/IP和超文本传输协议。DCOM是作为Windows操作系统中的一部分集成的。DCOM将很快在所有的主流UNIX平台和IBM的大型服务器产品中出现。DCOM替代了OLE远程自动控制。

在提供一系列分布式范围方面,DCOM通常与通用对象请求代理体系结构(CORBA)相提并论。DCOM是微软给程序和数据对象传输的网络范围的环境。CORBA则是在对象管理组织(OMG)的帮助下,由信息技术行业的其他商家提供赞助的。

5.3.2   MTS

然而,只有DCOM模型来构架程序是不够的,该类组件必须使用共同的服务框架,于是,MTSMicrosoft Transaction Server)是继DCOM出现后,微软为其Windows NT操作系统推出的一个中间件产品,它具有强大的分布事务支持、安全管理、资源管理和多线程并发控制等特性。其目的是开发、部署并管理高性能、可缩放并且强健的服务器应用程序。为了管理企业的应用程序,MTS定义了编程模型并提供了运行时环境和图形管理工具MSDTC。最重要的是,它与Windows操作系统紧密结合,是操作系统的一部分,而不是像WebLogicWebShape等第三方中间件服务器。

5.3.3   COM+的出现

早在1997年,MICROSOFT已经宣布了COM+的一些概貌,随着Windows2000的发布,COM+作为融合在操作系统中的组件技术将会在以后越来越被广泛使用。

COM+并不是COM的简单升级,COM+的底层结构仍然以COM为基础,它几乎包容了COM的所有内容,COM+综合了COMDCOMMTS这些技术要素,它把COM组件软件提升到应用层而不再是底层的软件结构,它通过操作系统的各种支持,使组件对象模型建立在应用层上,把所有组件的底层细节留给操作系统,因此,COM+与操作系统的结合更加紧密。

COM+不再局限于COM的组件技术,它更加注重于分布式网络应用的设计和实现。COM+继承了COM几乎全部的优势,同时又避免了COM实现方面的一些不足,把COMDCOMMTS的编程模型结合起来,继承了它们的绝大多数特性,在原有的特性上增加了新的功能,比如负载平衡、队列服务、内存数据库、事件服务、COM+对象池、管理服务、安全性等。

COM+标志着Microsoft的组件技术达到了一个新的高度,它不再局限于一台机器上的桌面系统,它把目标指向了更为广阔的企业内部网,甚至Internet国际互连网络。COM+与多层结构模型以及Windows操作系统为企业应用或Web应用提供了一套完整的解决方案。

最后,以一个图例展示它们之间的头条:

COM+组成结构图(图10

6       COM+与分布式事务

对于COM+,要想全面的理解,需要深入并用大量篇幅来描述,请参考《对象组件技术COM+概述.doc》,本文的重点是了解COM+中的事务处理,因此,在此只讲述COM+事务。

在三层或者多层的架构应用中,COM+的事务功能运用的比较多。COM+事务的功能是非常强大的。COM+使用Microsoft Distributed Transaction Coordinator(DTC)作为事务管理器和事务协调器在分布式环境中运行事务。COM+事务的强大功能表现在:可以在多个数据库中操作数据,处理消息队列等,把这些操作作为一个原子操作。他是一个基于操作系统级别的事务。

COM+继承MTS的事务语义,通过SetAbortSetComplete完成事务操作。COM+还支持其他的事务操作模式,如果一个对象被标为“AuotAbort”,那么在事务操作过程中,若发生异常,则系统自动调用SetAbort。同样地,如果一个对象被标为“AutoComplete”,那么在每一个方法调用之后,除非此方法显式调用了SetAbort,否则系统会自动调用SetComplete。而且COM+还支持BYOT(Bring Your Own Transaction),即允许COM+组件参与非MTS事务处理环境管理的事务。通过设置COM+组件的Transaction Support属性,让COM+组件支持相应事务类型。

单个组件能够在单个com+事务中对不同类型的数据源执行操作。当与组件一起使用com+声明事务时,能影响adoole db数据访问。在单个事务中能够操作的数据源的可能组合是无止境的。例如, com+对象能够在sql server数据库中修改数据、发送msmq消息,以及操作来自大型机系统的数据,所有这一切都在相同的com+事务中。

6.1        Transaction Support所支持的属性:

l         禁止( disabled )当组件的transaction support属性设置为disabled时,com+将完全地忽略组件的事务要求。com+首先试图在创建者的环境内激活对象。如果创建者的环境是无效的或不兼容的, com+在一个新的环境中激活对象。由于对象可能继承或不继承创建者的环境,则对象也就可能共享或不共享创建者的事务。

l         不支持(not supported)当组件的transaction support属性设置为not supported时,组件的实例决不参与事务。这种设置是为不访问数据源的com+组件设计的,其结果是组件没有事务开销。然而, transaction support属性为not supported的对象总是在一个新的环境中被激活。这与disabled相矛盾, disabled的对象可以共享创建者的环境。not supported是缺省的transaction support属性值。

l         支持(supported)当组件的transaction support属性设置为supported时,组件的实例参与存在的事务。但是组件对事务并没有要求,组件在事务不存在的情况下仍能很好地执行。supported属性只是表示支持事务,而不是必须要求事务存在。

l         需要( required )当组件的transaction support属性设置为required时,组件的实例总是在事务内执行。在激活com+对象前, com+将使用创建者的事务(如果存在),或者新的事务提供对象。不管哪种情况,组件实例总是在事务内执行。

l         需要新建(requires new)当组件的transaction support属性设置为requires new时,总是在一个新的事务中激活组件的实例,即专为这个对象创建一个事务,而不管是否存在可用的事务。这个设置为必须在事务中完成工作,但又必须把它的工作与所有其他的事务分开的组件而设计的。使用这个设置时, com+对象永远不会运行在创建者的事务中。新的事务完全独立于创建者的事务。

重要的是记住只有Transaction Support属性不是DisabledNot Supported时组件才需要参与事务。COM+组件同样能可选地表决事务的结果。在COM+中,事务具有四个生存周期:事务开始、建立并征募与Resource Manager的连接、在事务中执行操作、输出事务结果并结束。下面描述一下在单个和多个对象的COM+事务中,事务生存期的每一阶段的具体情况。

6.2        活动与同步

当事务处理系统为许多用户提供服务时,能从客户中接收同时发生的调用。因此,事务处理系统必须考虑像多用户并发、同步和线程管理等问题。COM+能够处理这些问题,而且允许创建在多用户分布式环境中执行的组件,其创建过程同创建为单个用户服务的组件一样。

COM+通过使用活动(activity )来完成这个惊人的任务。在MTS中,活动是一个对象组,这些对象都在代表单个客户运行。在COM+中,活动是一个环境组,这些环境在代表单个客户运行,环境可能含有一个或多个对象。然而,这仅是一个微小的差别,并且可以认为环境是最内部的对象容器。

活动确保服务于同一用户的两个对象不会同时执行。在一个活动中的对象被同步以阻止在这个活动中并行地执行。活动可以由几个环境(包含着对象)组成,可以运行在分离的进程中,或者运行在分离的机器上(稍微有一点限制)。由于这些原因,活动有时指的是运行的单个逻辑线程。

为什么对象的同步如此重要?考虑一个最糟糕的情况,在完全相同的时刻,代表同一用户服务的两个对象试图访问相同资源。每一个对象要完成自己的操作,就要阻塞其他对象的运行。这种情况称为死锁。活动能防止发生死锁,这是通过每次只允许一个对象代表一个用
户运行来实现的。另外,活动在帮助com+管理线程缓冲方面起着重要作用。

mts中,活动内对象的同步是通过将活动连接到单个物理线程,或是一个sta实施的。在一个活动中的对象不能并发执行,因为每个活动仅有一个物理线程。另外, com+使用复杂的锁定机制来确保活动中的同步。

每个活动保持着单一的独占锁。当在对象中调用一个方法并且对象的环境存在于一个活动中时,在允许处理方法调用前, com+首先要试图获得活动锁。如果获得锁,就由对象处理调用,直到方法调用完成,才解除锁。如果不能获得锁,就阻塞方法调用,直到获得锁才调用方法。虽然锁定过程更加复杂,但从高层次观点看, com+使用逻辑的活动使得多个环境和多个对象同步,基本上就是每一活动用一个单独的锁。

环境能存在于创建者的活动或一个新的活动中或者根本没有活动。然而,单个环境不能跨越多个活动。为了建立和保持这些关系, com+为每个活动创建独特的用户标识符,称为activity id,存储于每个环境中。

synchronization属性有五种可能的值:

l         禁止(disabled) 当组件的synchronization属性设置为disabled时,com+将完全地忽略组件的同步要求。正如当transaction support属性设置为disabled时, com+将首先试图在创建者的环境中激活对象。如果创建者的环境无效或不相容, com+将在一个新的环境中激活对象。如果对象继承创建者的环境,则对象可以分享创建者的活动,反之不能。应该在非事务性组件中使用这种设置,无论何时,应尽量避免创建环境和活动的额外开销。

l         不支持(not supported) 当组件的synchronization属性设置为not supported时,对象的环境将不存在于活动中。然而,synchronization属性为not supported的对象总是在一个新的环境中被激活。

l         支持(supported) 当组件的synchronization属性设置为supported时,对象的环境是否存在于活动中依赖于创建者的环境是否存在于活动中。然而,具有这种设置的组件不需要活动,而且在没有活动的情况也能很好地执行。

l         需要(required) 当组件的synchronization属性设置为required时,对象的环境将总是存在于活动中。如果创建者环境存在于活动中,则新的对象将在创建者的活动中激活。否则,com+将在位于新活动中的新环境里激活对象。

l         需要新建(requires new) 当组件的synchronization属性设置为requires new时,对象的环境将总是在新的活动中创建,不管创建者的环境的同步状态如何。

正如你所看到的,synchronization属性的选项和transaction support属性的选项非常相似。然而,某些synchronization选项依赖于其他组件属性的某些值。特别是,支持JIT激活的组件或transaction support属性为supportedrequiredrequires new的组件必须在活动中被激活,而且需要synchronization属性为requiredrequires new 。只有当jit激活被关闭并且transaction support属性设置为disablednot supported时,synchronization属性才能设置为disablednot supported。我们将在下一节更多地讨论事务与活动的关系。

6.3        事务的生存期

COM+事务生存期可分为四个阶段,分别是:事务开始、建立并征募与resource manager的连接、在事务中执行操作、输出事务结果并结束。

下面详细看一下在单个和多个对象的com+事务中,事务生存期的每一阶段的具体情况。

6.3.1   事务开始

使用COM+事务模型,组件不会显式地启动一个com+事务。相反,com+在两种情况下自动地创建一个新的com+事务:

l         transaction support属性为required的组件由非事务性的客户激活。

l         transaction support属性为requires new的组件由任何客户激活。

一个com+事务由两部分组成:

l         逻辑事务。

l         物理事务。

逻辑事务也称为事务流,是共享一个物理事务的对象的一个逻辑集合或逻辑组。另一方面,物理事务是基本的ms dtc事务,使用两阶段提交协议,根据数据源协调事务结果。当物理事务由com+创建时,它使用最高级别的隔离(可串行的)创建,并且在组件服务浏览器中指定事务超时间隔。com+从基本的物理事务中完全地抽象对象,而不是让我们通过逻辑事务流和每个对象的环境管理事务。

尽管逻辑事务可以由几个com+对象组成,但是事务流(逻辑事务)与物理事务始终存在一一对应关系,这一点非常重要。

在事务流中创建的第一个对象,称为事务的根。事务的根能够通过实例化组件在同一事务中可选择地征募其他的com+对象,这些被实例化的com+组件的transaction support属性为required或者supported。在这同一事务中创建对象时, com+自动地将根对象的环境事务信息复制到新的对象环境中,因此com+能在事务中维持所有对象之间的关联。事务信息包含一个称为transaction idguid值,COM+用它识别物理(ms dtc)事务。

将被征募到创建者的事务中的新对象必须在相同的活动中创建。利用mts,这意味着根对象必须使用objectcontext对象的createinstance方法创建子对象。现在com+已经使mtscom编程模型成为一体,不再需要createinstame方法,子对象能用visual basic 中的createobject函数或visual c++中的c o createinstance函数创建。
com+
事务从不跨越活动,但活动与com+事务不总是一一对应的关系。单个活动可能会有几个com+事务。如果一个com+对象实例化一个transaction support属性为requires new com+组件,这个新的对象将在同一活动中,但是在不同的com+事务中,这个事务完全独立于创建者的事务。

通常由com+运行期自动创建物理和逻辑事务, com+也允许开发者在已存在的ms dtc (物理的)事务中创建com+对象。这个特征被恰当地称为带着自己的事务” ( bring your own transactionbyot )。开发事务性组件时,这个特征给开发者提供了更多的灵活性,同时仍然能利用com+的简单性和逻辑事务模型。有了byot,组件能有效地应用ms dtccom+编程模型的组合来虚拟地完成任何事务任务。byot的典型用途是创建具有不同属性的ms dtc 事务,例如低于可串行化的隔离级别,然后在物理事务中创建一个或更多的com+组件。

6.3.2   建立与resource manager的连接

创建了逻辑事务和基本的ms dtc(物理的)事务后, com+必须确保所有由c++对象执行的对数据源的数据修改操作在ms dtc(物理的)事务中执行。每个数据源的每个连接必须从征募到或注册到ms dtc事务。

一旦这样做了,所有的操作都通过此连接执行并由ms dtc监控。虽然对每个连接的整个征募过程由com+在幕后完成,但是必须明白在事务的整个生存期中如何完成这一重要步骤的细节。

resource manager(rm)是数据库服务器的一部分,它使用com+管理持久的数据。因此对特定的数据源的连接事实上仅是对resource manager的连接。但是,com+事务模型在分布式的事务体系结构中增加一个软件层,称为resource dispenser (rd)

不要把resource managerresource dispenser混淆,他们是在com+事务模型中用于不同目的的两个不同的软件组件。

resource manager是一个简单的系统服务。例如数据库系统,它在分布式事务中管理着持久性资源。

ms dtc利用resource manager协调事务的提交和回滚,这通过使用两阶段提交协议实现。resource manager的例子包括:sql serveroraclemsmq等。

另一方面, resource manager 是一个进程内的动态链接库,它管理存入resource manager的内存中的非持久的或临时的资源。例如数据源连接、网络连接、线程和内存数据块等。在系统出现故障时不需要保护这些共享资源。

resource manager 能管理可再用资源的缓冲池,在事务中自动地征募或注册他们,为com+对象提供针对这些资源的操作方法和接口。一个由resource manager管理的最普通的非持久性资源是与控制永久性存储的底层resource manager的连接。

不要让resource manager这个术语迷惑了。resource manager和用于访问资源的组件是一样的。例如, ole db服务组件总是驻留在使用adoole db的客户应用程序或者对象与ole db提供者及数据源之间。com+指定ole db服务组件作为resource manager,将数据

源作为resource manager

前面早已提到,作为resource manager,这些软件组件负责管理非持久的资源。但是它们也能可选择地提供两个重要的服务:

l         资源缓冲资源缓冲是通过给com+对象提供一个再循环的资源而不是创建新的资源,提供了一个有效地分配非持久性资源的方法。com+对象使用完资源后,将资源放回缓冲池中,这样它或其他的com+对象可以立刻再使用这些资源。到数据源(resource manager)的连接是所使用的非持久资源中最普通的一个。创建和取消一个到resource manager的连接是一个“昂贵”的过程。为了有效地给com+对象提供数据源连接,odbc驱动程序管理器和ole db服务组件都提供resource manager连接的缓冲,昂贵资源的重用或循环对消耗这种资源的com+对象或应用是完全透明的。

l         事务征募事务征募(enlistment )是关联或征募具有ms dtc(物理的)事务的resource dispenser的连接的过程。一旦完成事务征募,所有的工作由com+对象通过此连接执行,并且由ms dtc监视并在分布式的事务中得到保护。所有的操作将作为单一的工作单元执行,事务作为一个整体需要确定其acid属性。当逻辑事务完成时, ms dtc对所有参与的resource manager 执行两阶段提交协议。事务征募是完全可选的, resource dispenser决定是否在当前事务中征募资源。事务征募通过简化事务性com+组件的开发在com+事务中起着重要作用。

com+通过对组件隐藏分布式事务复杂的细节来完成任务。事实上,在事务生命期的此阶段中,唯一要做的是建立与数据源的连接,就像平常使用adoole dbodbc一样。com+resource dispenser负责执行资源缓冲和事务征募。

6.3.3   执行操作

一旦建立数据库连接, com+对象能依靠resource manager开始执行操作。
resource manager接收和处理这些数据时,能采用相应的方法确保事务满足acid要求。许多resource manager实现一个日志机制,提供回滚未提交的变化的能力,满足原子性的要求。通过再应用或恢复未预料问题引起的变化,日志机制也允许resource manager确保事务的持久性。锁用于隔离事务的变化,使其他针对同一resource manager的事务不受这些变化的影响。为确保一致性,resource manager通常定义特殊的机制或规则保护数据的完整性。

6.3.4   表决事务的结果

前面已提到,事务性com+对象的环境包含称为transaction idguid值,它用于在事务中关联多个对象,并将逻辑事务链接到底层的物理事务。然而,这仅是存储在对象环境中的部分信息。事务对象的环境也包含两个其他的重要信息,它们用于完成事务,表决事务是提交还是终止。这两部分信息是:

l         完成标志(done bit) done bit是个布尔值,表明对象是否应该失效, ture值显示对象已经完成它的工作,且可以失效, false (缺省)值表明对象不能失效。
在方法调用完成之前, com+不检测done bit的值。因此,done bit值能改变许多次,它的值在方法调用之后才有意义。done bit事实上是由j i t激活提供的,所以,可用与非事务性组件相同的方法支持j i t激活。

l         一致性标志(consistency bit) consistency bit有时称为“ happy bit”,它是一个布尔值,它显示com+对象决定是提交还是终止事务。ture值显示对象试图提交事务, false 值显示对象要强迫终止事务。

对象失效(done bit 设置为ture )后, consistency bit 才由com+用于判断。因此,consistency bit值可以重复地修改,甚至在不同的方法调用中也可以修改,因为只有对象失效前的最后值才是事务表决要用的。com+ture值初始化consistency bit,即com+假设事务是想提交的

当事务的根失效时(根对象的环境的done bit设置为ture )com+在事务流中对每个环境的consistency bit赋值,来决定事务结果。试图提交事务的决定是意见一致的决定。
如果在事务中所有对象设置它们的环境的consistency bitture,表决企图提交事务,则在事务中执行的所有操作企图进行永久性的提交。然而,如果事务中任何对象设置它的环境的consistency bitfalse,表决终止事务,则在事务中完成的所有操作将被回滚。当这两种情形的任一种发生时, com+调用退出ms dtc,提交或终止这个物理事务。ms dtc然后通过使用两阶段提交协议负责与所有征募的resource manager协调分布式事务的提交或终止过程。下表概述了done bitconsistency bitcom+事务的结果的影响:

Done Bit

Consistency Bit

COM+事务的结果

TRUE

TRUE

COM+MSDTC将试图提交事务

TRUE

FALSE

COM+MSDTC将终止事务

FALSE

TRUE

直到根对象被激活,才能提交或终止事务

FALSE

FALSE

直到根对象被激活,才能提交或终止事务

我们了解了done bitconsistency bit取什么值能够提交或终止com+事务。下面介绍如何检索和修改它们的值。

object context(i objectcontext )接口的方法可能是编程控制com+事务结果的最容易的方式,因为这种方式允许调用单个方法同时设置done bitconsistency bit。由于donebitconsistency bit之间有四种可能的组合,所以存在由objectcontext接口定义的四个方法,它们分别是: SetCompleteSetAbortEnableCommitDisableCommit。下表所示中,每一个对象环境的方法合相对应。与done bitconsistency bit值的一个独特组合相对应。

对象环境方法

Done Bit

Consistency Bit

SetComplate

TRUE

TRUE

SetAbort

TRUE

FALSE

EnableCommit

FALSE

TRUE

DisableCommit

FALSE

FALSE

l         SetComplete方法:setcomplete方法告诉com+,一个特定的工作单元已经成功地完成。通过设置done bitconsistency bit都为turesetcomplete方法强迫对象取消激活并表决要提交事务。只有在根对象中调用setcomplete方法时,com+才将在每个对象的环境中检查consistency bit以决定事务结果。

l         setabort方法:setabort方法告诉com+,对象没有成功地完成它的工作,它想终止事务。如果一个或多个的com+对象在事务中调用setabort方法,由于setabort方法设置了consistency bit falsedone bitture,整个事务将终止。

l         enablecommit方法:enablecommit方法告诉com+,对象能提交事务,但对象尚未被取消激活。enablecommit方法通过设置consistency bitturedone bitfalse完成这一任务。

l         disablecommit方法:disablecommit方法正好与enablecommit方法相反。disablecommit方法告诉com+,对象的工作没有完成,事务不能在当前提交,对象也不想取消激活。disablecommit方法设置对象环境的consistency bitdone bit都为false。由于对象仍然激活,在方法调用之间将保持其状态。

l         结束事务的其他方式:事务超时;客户释放所有对事务根的引用当客户释放对根对象的最后一个引用时, com+隐含地试图提交该事务。隐含的事务提交过程通常应该被避免,因为这会引起主机出现问题。

6.4        事务生存期小结

事务在它的生存期中经历的整个过程听起来很复杂,重要的是记住,对参与事务的com+组件的唯一要求是给它们配置相应的transaction support属性。有许多不同的技术为提交或终止一个事务提供了灵活性,尽管现在理解它们还有一点困难,但它们使得开发基于组件的事务性系统更容易。

7       .NET中开发COM+实现分布事务

现在,分布式事务听起来挺不错,但实际应用中,并不是如此,它只是尽可能的降低数据不一致的可能性,并不能完全避免。因为COM+是由MSDTC管理的,而MSDTC有时显得很脆弱,而且COM+资源占用也比较严重。

但是,有时,还是需要用到COM+事务功能,在.NET中,提供了编写COM+组件的包装类System.EnterpriseServices.ServicedComponent

7.1        开发事务型COM+组件

l        实现一个COM+Configured

只用从System.EnterpriseServices.ServicedComponent继承一个自己的类,然后提供一个缺省的构造函数

l        声明分布式事务

在类名前面加事务属性即可,如:[Transaction(TransactionOption.Required) ]

l        提交事务

在方法内调用ContextUtil.SetComplete()是在方法上直接使用自动完成属性 [AutoComplete()]

l        编译和分发

d)    组件注册,在程序集中加入如下代码:

[assembly: ApplicationName("MydotNetCOMApp")]

[assembly: ApplicationActivation(ActivationOption.Library)]

d)    组件强名称,在.NET中编写的COM+组件,需要强名称设置

[assembly: AssemblyKeyFile("keyfile.snk")]

这一步如果先用sn.exe 产生.snk文件然后在VS.NET IDE中打开AssemblyInfo.cs,加入上面的一行似乎更方便,这样就不用手工的csc编译了,VS.NET可以编译强名的Assembly。尝试使用AssemblyInfo.cs会更规范和统一。

d)    编译组件,

sn -k keyfile.snk

csc /out: dbClass.dll /t:library /r:System.EnterpriseServices.dll dbClass.cs

d)        发布登记

Regsvcs dbClass.dll Regsvcs自动调用regasm.exetlbexp.exe

 

7.2        COM+类示例

using System;

using System.EnterpriseServices; // COM+命名空间

using System.Reflection;

using System.Runtime.CompilerServices;

using System.Runtime.InteropServices;

 

[assembly: ApplicationName("COMPlusSamplesLib")]

[assembly: ApplicationActivation(ActivationOption.Library)]

 

//[assembly: AssemblyKeyFile("keyfile.snk")]

 

namespace dotCNetwork.dbClass

{

  /// <summary>

  /// COM+组件演示类

  /// </summary>

  [ObjectPooling(MinPoolSize = 2, MaxPoolSize = 50)]

   [Transaction(TransactionOption.Required)]

   [Synchronization(SynchronizationOption.Required)]

   [ClassInterface(ClassInterfaceType.AutoDual)]

   [JustInTimeActivation(true)]

   [Guid("569A14C1-5DAD-4c8f-BB48-89DDD89FAD7A")]

  public class Author : ServicedComponent

  {

       public Author()

       {

            // COM+组件必须提供一个缺省的构造函数

       }

      

       //JIT/Pooling

       protected override void Activate()

       {}

      

       // JIT/Pooling

       protected override void  Deactivate()

       {}

      

       //JIT/Pooling

       protected override bool CanBePooled()

       {

            return true;

        }

      

       // 需要显示调用SetComplete方法提交事务的过程

       public bool TestFunc()

       {

            try

            {

                // 代码

                //...

                ContextUtil.SetComplete(); // 此句提交事务

                return true;

            }

            catch(Exception e)

            {

                            ContextUtil.SetAbort(); // 如果异常,则回流事务

                return false;

            }

       }

      

       // 此过程被调用完自动提交事务,如果异常,则自动回流事务

       [AutoComplete]

       public bool TestFunc2()

       {

            // 代码

            //...

            return true;

       }

  }

}

7.3        利用TransactionScope类实现分布式事务

除了编写COM+组件外,也能实现分布式事务,那就是利用 TransactionScope类,TransactionScope不限于一个单独的数据库链接。它最常用的一个案例是在多台服务器上运行一个事务。

当一个TransactionScope对象被创建时,它会自动将自己注册成线程的事务。所有的事务感知操作也将会自动地使用这个事务,而不需要将事务对象传递给对象。事务感知对象的例子包括SQLCommand类和LINQ to SQL对象。不过这种设计的一个比较严重的副作用是事务和操作间的连接不是那么直接。

       用法是将一个完整事务的代码包含在创建 TransactionScope类和销毁这个类之间,如下面的示例代码:

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

          {

                ServiceDA da = new ServiceDA();

                int result = da.CreateTable1(2);

                if (result != 0)

                {

                  

                }

                result = da.CreateTable2(2);

                if (result != 0)

                {

             

                }

                ts.Complete();

            }

7.4        SQLServer2000中实现分布式事务

在这里,一起讲解一下在SQLServer2000及以上版本中实现分布式事务。要在SQLServer中用SQL脚本(通常是存储过程)中实现分布式事务,必须要先在SQLServer所在服务器上配置了MSDTC,配置MSDTC的操作参看下面的第9章节。然后,打开查询分析器,执行如下操作:

l        SQLServer中注册链接SqlServer服务器:

通过调用存储过程sp_addlinkedserver 或者在Server Object中添加

EXEC sp_addlinkedserver @server='linkServerName', @srvproduct = 'SQL Server'

EXEC sp_addlinkedserver @server='linkServerName', @srvproduct='', @provider='SQLNCLI', @datasrc='sqlServerName'

关于这个存储过程的用法,具体参数可以参口Microsoft SQLserver 联机帮助文档中关于 sp_addlinkedserver中的详细说明,可以通过直接连接方式连接大多数数据库或者本地文件,也可以通过ODBC方式进行连接。

l        通过 sp_addlinkedsrvlogin添加链接服务器的访问用户:

sp_addlinkedsrvlogin [ @rmtsrvname = ] 'rmtsrvname'

     [ , [ @useself = ] 'useself' ]

     [ , [ @locallogin = ] 'locallogin' ]

     [ , [ @rmtuser = ] 'rmtuser' ]

     [ , [ @rmtpassword = ] 'rmtpassword' ]

7.4.1   访问格式:

访问对方数据库格式为:

[servername/instancename].[database].[dbo].[Object]

其中的Object指:表、存储过程、视图等

7.4.2   示例:

     下面的示例中,语句BEGIN DISTRIBUTED TRANSACTION表示要开启分布式事务,执行 BEGIN DISTRIBUTED TRANSACTION 语句的服务器是事务创建人,并且控制事务的完成。当连接发出后续 COMMIT TRANSACTION  ROLLBACK TRANSACTION 语句时,主控服务器请求 MS DTC 在所涉及的服务器间管理分布式事务的完成。其实质上,还是利用MSDTC来实现分布式事务的控制。
USE pubs
GO
BEGIN DISTRIBUTED TRANSACTION
UPDATE authors
   SET au_lname = 'McDonald' WHERE au_id = '409-56-7008'
EXECUTE remote.pubs.dbo.changeauth_lname '409-56-7008','McDonald'
COMMIT TRAN
GO

8       .NET开发COM+注意事项

在数据库的连接串中把Enlist设置为true 缺省为true),如果设置为false,则用此连接串建立的连接对象不会参与到分布式事务中;

双方都要启动MSDTC服务并进行必要的如下配置;

9       配置与部署COM+

9.1        配置MSDTC

1、 开户MSDTC,组件服务-我的电脑-右键属性

 

2、  打开MSDTC选项卡

3、  打开安全配置,如图配置

 

9.2        打开双方135端口

上一步配置完之后,利用DTCPing工具测试。把DTCPing拷贝到所有这些服务器上,并且进行双向的连通性确认。双向是说A->B得通,B->A也得通;如果双向都能连通,说明135端口已开通并且能正常通信,否则,要察看是否有防火墙阻止了,网线不通等等原因。

9.3        注册COM+服务

调用.NET提供的程序regsvcs.exe 注册,关于regsvcs.exe的用法,可以在CMD中键入regsvcs.exe /?了解,示例:

regsvcs.exe ServiceLib.dll

当然,regsvcs.exe的路径要在Windows的环境路径中,否则,就要键入全路径(如C:/WINDOWS/Microsoft.NET/Framework/v2.0.50727/regsvcs.exe)。注册成功后,在MSDTC中刷新,会看到。

10             开发中碰到的错误及处理办法

如果碰到不能成功注册COM+,首先看编写的代码是否遵守了上面编写约定;

检查MSDTC配置是否正确;


 

 

 

 

参考来源:

SQLServer联机帮助文档;

网上查阅;

自己浅薄的知识;

 

最后,要感谢网络:

是网络,让我们的生活变得丰富多彩;

是网络,让我们获取知识变得快捷。

 

 

杨连山

2008-01-04