全面接触微软事务处理服务MTS

一、引言

  随着软件业的发展,软件开发的理论和经验越来越大的改变了我们系统开发的模式。应用程序的开发从两层结构模型发展到了三层甚至是多层的结构模型,一般可以分为表示层、业务逻辑层和数据库处理层。
  
  实际上,我们可以通过使用快速开发工具比如VB,DEPHI,HTML页面生成工具(如FrontPage,Dreamweaver)等来快速构建表示层,通过一些相对独立的组件来建立业务逻辑层,比如通过DLL或者COM组件的形式,当然DLL存在版本和存放位置不独立的问题,所以当前基本上以采用组件技术为主,而在Windows操作平台上最常使用的就是COM组件。我们知道,COM技术是微软前几年操作系统和应用系统开发的一个核心的技术,它实现了基于二进制的代码的共享,并且解决了DLL所无法解决的版本问题,同时也实现了组件位置无关性,使Windows操作系统无缝的从桌面平台延伸到以网络为基础的平台上。

  至于后台数据处理,我们可以通过大型的数据库(Oracle,SQL SERVER,DB2等)和工作流服务器(比如Exchange、Notes等等)来保存企业关键的信息和数据。但是对于企业来说,如何保证数据的安全性是一个非常关键的问题,数据的安全基本有两个层面的含义,一个是在数据库中的安全性,这个是由数据库本身来解决的,一个是数据调用和传输的安全性,这个主要在业务逻辑层实现。
 

  另外,随着企业规模的扩大,业务的增加和数据流量的扩展同时也需要保证系统运行的高效性,这就要求系统能够动态进行扩展,当然数据库的扩容技术相对已经比较成熟,而表示层基本不涉及效率方面的问题,所以业务逻辑层就成了最关键的一个检查点。同时,我们需要对业务逻辑进行方便的管理和配置,以便适应企业业务的需求,所有这些都对业务逻辑层提出了严格的要求,当然,我们开发人员也可以自己构建一个完整的业务逻辑层来安全性、扩展性和可管理性等方面的要求,但是这有两个问题,一个不够标准化,第二个要花费开发人员大量的精力,从这个角度出发,微软开发了MTS系统,把对逻辑组建的管理都集中到这个事务处理器上来执行,也就是说, MTS关心的就是业务逻辑层的东西。

二、MTS的提出

  尽管组件技术的出现,使软件开发的效率大大得到了提高,但是也出现了一些问题。比如如何实现对COM组件的事务处理和安全管理是COM组件出现后所面临的一个重大的问题,为了解决这个问题,微软推出了MTS系统,MTS使企业应用的开发人员把精力集中在对业务逻辑开发的基础上,而组件本身的安全性和通讯以及事务处理方面的问题交由MTS来进行处理。

  MTS能够自动进行组件的事务处理和安全性配置。同时,MTS在数据库应用系统方面也表现了极强的能力,它能够使以数据库为核心的应用程序更好的和数据库进行交互,我们知道应用程序对数据库进行操作的时候,实际上都是通过和数据库建立一个连接,当处理完成后就释放这个连接,也就是说,这个连接实际上是由开发人员自己进行管理的,而出现了MTS以后,开发人员就不必去关心这个连接,它的释放完全交给MTS来进行处理,这样的好处是比如如果一个用户使用完一个连接以后,而另外一个用户要申请一个连接的话,可以马上就重用这个连接而不需要去重新创建一个连接,这样就降低了系统的开销。

  另外,值得一提的是,MTS并不是仅仅支持SQL SERVER数据库,它同时还支持DB2和ORACLE等大型数据库系统。其实只要细心的开发人员就可以注意到在安装了MTS以后,在ODBC的设置上多了一个连接池(Connection Pooling)选项,这个实际上就表示MTS接管了对数据库连接的管理。

  同时,MTS实现了复杂的组件管理技术,它能够自动支持组件的事务处理,能够进行基于角色(role)的安全管理,能够和各种数据库进行通讯,能够和MSMQ进行无缝集成,能够对组件的状态进行管理,通过一定的调度算法来实现对组件的操作。而且,单个应用可以被分隔成不同的包(package),不同的包实际上是在不同的进程中运行的,这样应用系统的容错能力就大大提高。

  在具体开发领域,MTS允许开发人员用任何开发语言来建立应用系统,可以采用VB,VC,JAVA等开发工具。这里需要提到的一点是在微软以后的操作系统(Windows XP)中不再支持JAVA,实际上微软已经实现了一个C#的开发语言,它在功能和使用上要比JAVA更加方便和灵活(当然客观的讲,它能够比JAVA好的原因是它比JAVA推出的晚,可以修补JAVA的各种不足的地方,另外,它和.NET Framework有着紧密的联系)。
  
  当然在WinNT环境下,MTS还是大有用武之地,MTS能够方便的调用COM组件,同时采用图形化的界面对COM组件进行管理,因此方便了基于COM服务器的应用程序的部署和开发。同时,MTS和微软的各种相关技术之间具有紧密的联系,比如Web服务器IIS和ASP剧本语言,NT集群(Cluster Service for Failover Protection)技术,同时和NT的认证安全技术紧密结合。

  基于MTS的三层体系结构图可以用下图表示:




  但是,在知道了MTS的作用和体系结构以后,我们如何构建一个能够在MTS下很好工作的组件呢?一般来说,需要遵守以下的准则:

  1. 通过一个简单的API调用(GetObjectContext),创建一个对MTS Context对象的引用,创建这个引用能够使组件充分利用MTS的优点,比如安全性和事务处理能力。

  2. 在组件中不要跨事务边界存储状态信息,一般来说,能够存储状态信息的组件的扩展性就会变差,因为当它们结束的时候,MTS不能循环使用它们的资源。所以,状态信息必须被保存在数据库中或者MTS的共享属性管理(Shared Property Manager)中,当需要的时候被组件所提取。

  3. 当一个组件完成执行的时候,它必须在MTS Context对象上调用SetComplete方法,用来告诉MTS,当事务中的所有的组件完成任务以后,组件希望提交所有的工作。同时也告诉MTS,它能够重用被该组件所掌握的资源。

  4. 如果一个组件不能成功的完成它的任务的时候,它必须MTS Context对象上调用SetAbort方法,用来告诉MTS它需要放弃当前的事务并进行相应的回滚(rollback),同时也告诉MTS,它能够重用被该组件所掌握的资源。
 
  三、MTS的操作和应用范围介绍

  需要注意的是,MTS是基于COM/DCOM技术之上的,主要在NT和9X平台上实现的(注意MTS是要从NT4 OPTION PACK上进行安装的),而随着W2K的推出,微软已经把重点放到COM+技术之上,COM+本身已经集成了MTS,在NT/9X平台上,你可以在“运行”对话框中输入“mtxexp.msc”来进行组件管理和配置。而这个管理工具在W2K下已经不存在了(注意W2K本身已经集成了组件事务处理功能,所以并不需要安装),你需要在“运行”对话框中输入“comexp.msc”来进行COM+组件的管理,需要注意的是,comexp.msc是在目录your_system_directory\system32\com之下的,你需要在环境变量的路径设置中加上“your_system_directory\system32\com”这个路径,以便在运行对话框中直接运行comexp.msc,当然在以后微软基于.NET Framework的操作系统版本推出后,所有的组件管理都要基于.NET运行库,其体系结构又要发生大的变化。

  现在,我们已经知道了组件是放在MTS下进行统一管理的,接下来的问题是应用程序如何来使用这些组件呢?实际上这些组件可以被不同机器上的应用程序来使用,前提是这些客户端机器必须安装MTS。客户端是通过DCOM来进行标准的组件信息传输的,当然在能够运行DCOM之前,你必须进行一些配置:

  1. 客户端注册表设置:最简单的方法是使用“Client Install Utility”这个工具,它能够自动对客户端的注册表进行设置,这个具体的配置是通过MTS Explorer来实现的(实际上就是mtxexp.msc这个东西)。下面的例子程序中会详细提到这一点。

  2. 必须在客户端和服务器端同时进行个性化(impersonation)和认证(authentication)权限的配置。缺省的对个性化的设置是“identity”,对认证的设置是“connect”。实际上,开发人员可以通过“DCOMCNFG”这个工具来实现对缺省设置的修改,当然实际上微软并不推荐这个方法,更好的方法是在MTS Explorer中在package这个层次上进行安全性的设置。

四、一个具体基于MTS的应用系统例子介绍

  下面举出一个具体的基于MTS的应用系统的实现例子(为了说明问题,我们采用VB语言来实现这个例子),注意该例子是用来说明MTS的使用的,而在W2K下是没有MTS这么一个单独的东西的,所以本例子适合于WinNT操作系统环境。

  主要步骤:

  1. 创建服务器组件

  首先,我们需要创建的是一个基于Active DLL的工程,我们创建的组件需要用到ADO对象,所以在创建服务器端组件的时候需要引用ADO类型库,同时因为需要使用MTS,所以也需要引用MTS类型库(实际上在W2K下,我们需要引用COM+ Services Type Library),这里我们把工程的名字设为MTSTest,需要注意的是,我们需要把线程模型设置为Apartment Threaded。

  增加如下的代码:

Option Explicit

Public Function Database_Test_Method(ByVal szConnect As String) As String

 On Error GoTo Errhandler

 Dim ctxObject As ObjectContext

 Set ctxObject = GetObjectContext()

 Dim cn As ADODB.Connection

 Dim rs As ADODB.Recordset

 Set cn = New ADODB.Connection

 With cn

  .ConnectionTimeout = 10

  .ConnectionString = szConnect

  .Open

 End With

 Set rs = New ADODB.Recordset

 rs.Open "select * from authors", cn, adOpenForwardOnly, adLockReadOnly

 Database_Test_Method = "First Value From Database:" & rs(0).Value

 rs.Close

 cn.Close

 Set rs = Nothing

 Set cn = Nothing

 ctxObject.SetComplete

 Exit Function

 Errhandler:

  ctxObject.SetAbort

  Err.Raise vbObjectError, "MTSTest.Class1.Database_Test_Method",   Err.Description

  Exit Function

End Function

Public Function General_Test_Method() As String

 On Error GoTo Errhandler

 Dim ctxObject As ObjectContext

 Set ctxObject = GetObjectContext()

 General_Test_Method = "String from Gereral_Test_Method"

 ctxObject.SetComplete

 Exit Function

Errhandler:

 ctxObject.SetAbort

 Err.Raise vbObjectError, "MTSTest.Class1.Database_Test_Method",  Err.Description
 
 Exit Function

End Function

  编译该工程并生成DLL文件

  2. 创建客户端应用

  用VB创建一个新的EXE工程文件,在Form上增加两个命令:Command1和Command2。

  增加如下的代码:

Private Sub Command1_Click()

 Dim obj As Object

 Set obj = CreateObject("MTSTest.Class1")

 MsgBox obj.General_Test_Method

 Set obj = Nothing

End Sub

Private Sub Command2_Click()

 Dim szConnect As String

 szConnect = "Driver={SQL
   Server};Server=YourServerName;UID=Sa;Pwd=;Database=pubs"

 Dim obj As Object

 Set obj = CreateObject("MTSTest.Class1")

 MsgBox obj.Database_Test_Method(szConnect)

 Set obj = Nothing

End Sub

Private Sub Form_Load()

 Command1.Caption = "Call General_Test_Method"

 Command2.Caption = "Call Database_Test_Method"

End Sub

  编译生成客户端程序

  3. 把服务器组件安装在一个MTS包中

  在MTS Explorer的GUI管理界面下,创建一个新的包(Package),选择倒入组件选项,把MTSTest.Class1倒入到包中,成为包里面的一个组件。

  现在你能够在服务器端成功的运行客户端(2步骤所生成的EXE文件)应用程序了。如果客户端应用程序在远地机器上运行的话,就需要进行步骤4。

  4. 对客户端机器进行设置

  这需要两个步骤:

  首先,利用VB的应用程序setup wizard创建客户端的setup程序,注意在制作过程中,移去所有对远地组件的引用。

  其次,创建和使用由MTS生成的客户端setup程序。这主要是通过MTS Explorer实现的,通过在Package项上选择Export,然后选择你想把该Package倒到什么目录上,然后wizard会帮你做其他的事情。

  然后把该目录整个放到客户机上,运行该目录的CLIENT子目录下的可执行文件,这实际上就是一个安装设置程序,它会对客户机的注册表进行适当的操作,注册远地的服务器。

  现在你就可以在远地的客户机上使用这个MTSTest.Class1这个COM组件了。 

 五、MTS和MSMQ技术的结合


  提到MTS就不能不提到MSMQ(Microsoft Message Queue)。我们知道,DCOM实际上是通过RPC(remote procedure call)来实现组件通讯的,而这个通讯实际上是通过同步方式实现的,但是许多应用系统需要通过消息队列来实现无阻塞的,异步的通讯模式,通过MSMQ,一个应用程序能够发送消息到另外一个应用系统中,然后不需要等待结果就可以返回(象Windows中进行消息通讯的API函数PostMessage一样),而且实际上对方的那个应用程序甚至不一定要处于运行状态。这些消息实际上是被放到一个队列中,发送者可以在它空闲的时候通过检查一个响应队列来判断该消息是否已经被处理完成。

  MSMQ服务可以通过一个简单的COM接口来被开发人员使用,这样就使所有使用COM的应用程序,甚至是ASP来直接的发送和接受消息。同时,MSMQ是支持事务处理的,也就是说它实际上是和MTS进行无缝集成的,基于MTS的应用程序可以在一个事务单元中进行消息的发送和接受,在一个事务中的所有的操作要么全部成功要么全部取消。

  另外,MSMQ支持进行日志记录,这样当操作出现差错的时候,能够自动进行再次操作。MSMQ对每一条消息的状态进行记录,这样就可以通知发送方该记录是否已经操作成功,以便发送方决定下一步的操作。MSMQ能够对在网络上进行传输的数据进行加密和数字签名,保证系统的安全性。当然,MSMQ也能够指定消息的优先级,让重要的消息被首先得到处理。更为令人惊喜的是, MSMQ可以在多个操作系统平台上得到,其中包括UNIX的多个版本。

  为了充分展示MTS和MSMQ结合对企业应用的作用,这里我们展示了一个基于COM,DCOM,MTS,MSMQ应用的例子,其体系结构如下:


  在这个例子中,我们实现了一个公司定单处理系统,系统可以以两种方式来接收定单:

  1. 允许客户通过Internet来下定单,这就需要通过一个ASP剧本语言来实现,客户可以访问公司的基于ASP的网页填写需要的货物数据,ASP剧本语言通过操作MTS管理下的定单录入组件来存储数据信息。

  2. 通过客户(录入相应的数据信息)和定单录入组件之间的直接联系而建立,实际上是通过DCOM来进行通讯的。

  这个系统的核心是一些COM组件,这些组件可以用来完成一定的商务逻辑,这些定单录入组件通过查看数据库决定某一个特定的货物是否有足够的库存,而且它们必须能够同时处理多个定单请求,相应的,这些组件是通过MTS来进行统一管理的,MTS同时提供了多数据库的事务处理。

  当一个定单被完成以后,定单录入组件就发送一个消息给仓库,告诉仓库这些货物必须被打包以便交给船务公司进行运送。因为定单录入组件没有必要等待仓库结果的返回就可以处理下一票业务,这个消息就被发送到MSMQ中。在仓库的应用程序在方便的时候从MSMQ队列中取出这个请求然后进行相关业务的处理。

  六、小节

  实际上,我们可以看到,MTS所提供的功能以及对应用系统体系结构的影响是巨大的,MTS使得COM能够真正成为企业级别的分布式的应用系统的基础框架。当然MTS也在不断改进,所以到了W2K时代,MTS被直接集成到COM+里面,而不在是一个独立的可以选择安装的组件。

  实际上在.NET Framework系统框架下,MTS的许多思想也被直接运用到里面。MTS以及其发展表现了当前软件发展的趋势,做基础平台的软件厂商提供的框架系统的稳定性、安全性和扩展性越来越好,而具体应用的开发人员只需要关注其应用所相关的领域,而不需要再去考虑系统级别上的问题,使系统的开发越来越快速和方便。
原文地址:https://www.cnblogs.com/jjkv3/p/2540105.html