⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 208.htm

📁 探索Windows 2000发展策略以及中介层技术设计的基本概念
💻 HTM
📖 第 1 页 / 共 5 页
字号:
<html><body><span  id=Layer1><p><font size=2 color=#3c3c3c face=arial>对於所有最简单的叁层式应用程式来说,将中间层(即商业逻辑)包装成COM元件是有意义的,让客户端可透过分散式的COM (DCOM),或从Web浏览器透过HTTP与Internet Information Services (IIS)存取这些元件。同时让这些元件使用ActiveX Data Objects (ADO)来存取储存资料也具有相当的意义。对於一些很简单的应用程式来说,这些技术可能已满足所有的需求。</span><span  id=Layer2></font></p><p><font size=2 color=#3c3c3c face=arial>不过大部份叁层式应用程式的中间层需要的不仅仅如此。举例来说,如</span><span  id=Layer3>&nbsp;<a href=207.htm# target=_new>前章</span><span  id=Layer4></a>&nbsp;所描述,企业级的应用程式通常会使用交易。在某些情况下,依赖资料库管理系统(database management system,DBMS)所提供的交易能力便已足够。若不足够,中间层软体的程式设计师可以直接使用分散交易协调者(Distributed Transaction Coordinator,简称DTC)。如果可以有一种通用的方式让中间层来进行交易处理,并隐藏不同的资料来源之间的异同,以及DTC的复杂性,那麽程式设计师的生活将会变得简单一些。</span><span  id=Layer5></font></p><hr><font face=Arial Black color=#3e77d7 size=3><b></b></font><p><font size=2 color=#3c3c3c face=arial>中间层COM物件有利於许多不同的服务使用</span><span  id=Layer6></font></p><hr><p><font size=2 color=#3c3c3c face=arial>或者思索一下∶将企业级应用程式扩展成拥有成千上万同时上线的客户端,这样的需求是很稀松平常的。若只使用一个标准的COM元件,却想要达到这种程度的延展性几乎是件不可能的任务,这必须靠应用程式设计师大量的工作方可完成。建立可延展的应用程式之通用机制,以及能够让许多不同类型的应用程式使用,可能会使建立叁层式应用程式更为简单也更为快速。然而还有其它的问题存在,也就是程式设计师得一再面对的中间层COM物件。</span><span  id=Layer7></font></p><hr><font face=Arial Black color=#3e77d7 size=3><b></b></font><p><font size=2 color=#3c3c3c face=arial>有用的服务包含了使用交易来建立可延展的应用程式等等</span><span  id=Layer8></font></p><hr><p><font size=2 color=#3c3c3c face=arial>若果真如此,为何不建立一个通用的解决方案呢?不用要求每位程式设计师重新建立一个自订的方法,较有意义的作法是提供一个标准的解决方案来面对这个问题。Windows 2000平台上的新产物,COM+,就是为了这个而存在的。它提供了一组服务来对付中间层程式设计师共同面对的问题。COM+包含了许多东西,不过Windows 2000第一次发行时,其中COM+ 1.0包含的主体是专注在建立可延展的、交易导向的中间层商业逻辑。</span><span  id=Layer9></font></p><hr><font face=Arial Black color=#3e77d7 size=3><b></b></font><p><font size=2 color=#3c3c3c face=arial>COM+为COM物件提供了一组功能强大的服务</span><span  id=Layer10></font></p><hr><a name=208001><font color=#3e70d7 face=arial size=5><b>从COM到COM+</span><span  id=Layer11></b></font><p><font size=2 color=#3c3c3c face=arial>Microsoft在1993年时首次让COM公开亮相,而DCOM是在1996年随Windows NT 4.0出货的。稍後在同一年便发行Microsoft Transaction Server (MTS),Windows NT 4.0 Option Pack的一部份。MTS第二版发行後只增强一些功能,基本架构并无太大改变。MTS是完全以COM为基础的(每个MTS应用程式都是设计成一个或多个COM元件)同时它提供一组有用的服务,以便建立叁层式应用程式中的中间层商业逻辑。但先不管这个问题,MTS是以COM的附加功能型式建立的。它并没有修改基本的COM基础架构,取而代之的作法是提供一个独立的程式库,称MTS Executive来提供它的服务。</span><span  id=Layer12></font></p><hr><font face=Arial Black color=#3e77d7 size=3><b></b></font><p><font size=2 color=#3c3c3c face=arial>MTS 为中间层的COM物件提供许多的服务</span><span  id=Layer13></font></p><hr><p><font size=2 color=#3c3c3c face=arial>而真实的状况是COM+整合了MTS与COM。MTS Executive已经告别了年代,它的功能现在已成为标准COM runtime的一部份。如</span><span  id=Layer14>&nbsp;<a href=205.htm# target=_new>第五章</span><span  id=Layer15></a>&nbsp;所描述,有些基本的COM基础架构,如CoCreateInstance也因为COM+ 的到来而大受影响。这些并不代表你无法使用最早在1993年定义的COM来建立应用程式  还是可以的。而COM+的主要目标是将MTS所提供的服务整合到标准的COM程式库,然後提供额外增强的功能。事实上,将增强版的COM+ 1.0视为MTS第叁版是不正确的。COM+从MTS扩增的服务包含∶</span><span  id=Layer16></font></p><font size=2 color=#3c3c3c face=arial><ul><font size=2 face=arial color=#3c3c3c><li><font size=2 face=arial color=#3e80d7><b>&nbsp;自动交易处理</span><span  id=Layer17>&nbsp;</b></font>(</span><span  id=Layer18><font size=2 face=arial color=#3e80d7><b>&nbsp;Automatic transaction</span><span  id=Layer19>&nbsp;</b></font>) 不需要客户端或中间层元件明确地定义交易开始、结束的时机,这个服务可让你以简单、元件导向的方式来使用交易。</span><span  id=Layer20></li><br></font><font size=2 face=arial color=#3c3c3c><li><font size=2 face=arial color=#3e80d7><b>&nbsp;物件生命周期服务</span><span  id=Layer21>&nbsp;</b></font>(</span><span  id=Layer22><font size=2 face=arial color=#3e80d7><b>&nbsp;Object lifetime services</span><span  id=Layer23>&nbsp;</b></font>) 聪明的使用伺服器机器的资源是建立可延展的应用程式之基本要素。COM+的及时启动(Just-In-Time activation,JIT)服务允许物件只在必要的时刻才启动,然後在不需要的时後自动地消失。主要的目标是增进应用程式的延展性(以此方式便可在使用相同的伺服器硬体这个条件下,支援众多的客户端)与正确性。物件集区(Object pooling)是COM+提供的另一种选择,允许将不再需要的物件置入集区中的快取,而非将其摧毁。稍後这个物件可以在集区中找到,然後在必要时重复使用。</span><span  id=Layer24></li><br></font><font size=2 face=arial color=#3c3c3c><li><font size=2 face=arial color=#3e80d7><b>&nbsp;执行绪与并行服务</span><span  id=Layer25>&nbsp;</b></font>(</span><span  id=Layer26><font size=2 face=arial color=#3e80d7><b>&nbsp;Threading and concurrency service</span><span  id=Layer27>&nbsp;</b></font>) 非多执行绪的伺服器应用程式若得让多个客户端同时存取时效率可能会相当地慢,因为每一个客户端都必需等待,轮流执行。很明显地撰写多执行绪应用程式相当的困难。COM+提供执行绪与并行服务让程式设计师更容易地撰写应用程式,这些应用程式立刻就可让多个使用者安全地存取。</span><span  id=Layer28></li><br></font><font size=2 face=arial color=#3c3c3c><li><font size=2 face=arial color=#3e80d7><b>&nbsp;安全性服务</span><span  id=Layer29>&nbsp;</b></font>(</span><span  id=Layer30><font size=2 face=arial color=#3e80d7><b>&nbsp;Security Services</span><span  id=Layer31>&nbsp;</b></font>) 不再需要更改ACL,或更糟的状况是更改应用程式的真正程式码,COM+提供授权服务(authorization service)允许程式设计师或系统管理者控制客户端能存取的资源,只要简单地设定一下应用程式的组态就行了。在管理上COM+同样也允许设定为了进行验证、资料完整性与资料隐密性的应用程式需求,或将或将这些资讯加到应用程式本身以移除这些需求。</span><span  id=Layer32></li><br></font></ul></font><hr><font face=Arial Black color=#3e77d7 size=3><b></b></font><p><font size=2 color=#3c3c3c face=arial>COM+ 能与MTS提供的服务相互运作</span><span  id=Layer33></font></p><hr><p><font size=2 color=#3c3c3c face=arial>这些所有的服务,还有更多的服务则由更新、且增强功能版本的COM runtime提供。为了要提供上述的服务,COM runtime便介入客户端对COM物件所发出的每一个method call之间,就如同MTS Executive在Windows NT 4中所做的一样。</span><span  id=Layer34></font></p><hr><font face=Arial Black color=#3e77d7 size=3><b></b></font><p><font size=2 color=#3c3c3c face=arial>COM+同样增加其它的服务</span><span  id=Layer35></font></p><hr><p><font size=2 color=#3c3c3c face=arial>在Windows 2000作业平台上首次发行的版本中,COM+同样包含了许多COM相关的服务,这些服务的根源不是在MTS中,它们包含∶</span><span  id=Layer36></font></p><font size=2 color=#3c3c3c face=arial><ul><font size=2 face=arial color=#3c3c3c><li><font size=2 face=arial color=#3e80d7><b>&nbsp;COM+ 事件</span><span  id=Layer37>&nbsp;</b></font>(</span><span  id=Layer38><font size=2 face=arial color=#3e80d7><b>&nbsp;COM+ Events</span><span  id=Layer39>&nbsp;</b></font>) 允许一个元件传送一个事件,让多个客户端接收是应用程式开发时一个很普通的需求。可建立一个一般的服务(有时称为发行与订阅模型)让这件事更容易进行。COM+事件提供这项服务,将事件以COM 物件的method 型式展现。</span><span  id=Layer40></li><br></font><font size=2 face=arial color=#3c3c3c><li><font size=2 face=arial color=#3e80d7><b>&nbsp;伫列元件</span><span  id=Layer41>&nbsp;</b></font>(</span><span  id=Layer42><font size=2 face=arial color=#3e80d7><b>&nbsp;Queued Components</span><span  id=Layer43>&nbsp;</b></font>) 往往客户端叫用COM 物件的method是属於同步的。客户端会一直等待直到呼叫回传。伫列元件带来非同步呼叫COM与DCOM物件method的型式,允许这些要求经由Microsoft Message Queuing (MSMQ)携带,而非透过远端程序呼叫(remote procedure call ,RPC)协定或其它的机制等进行。因为它对MSMQ的相依性,所以将在</span><span  id=Layer44>&nbsp;<a href=209.htm# target=_new>第九章</span><span  id=Layer45></a>&nbsp;介绍伫列元件。</span><span  id=Layer46></li><br></font><font size=2 face=arial color=#3c3c3c><li><font size=2 face=arial color=#3e80d7><b>&nbsp;元件负载平衡</span><span  id=Layer47>&nbsp;</b></font>(</span><span  id=Layer48><font size=2 face=arial color=#3e80d7><b>&nbsp;Component Load Balancing</span><span  id=Layer49>&nbsp;</b></font>) 当一个客户端呼叫CoCreateInstance,新物件潜在地可能会建立在许多台伺服器机器上。元件负载平衡提供一种服务,追踪一组伺服器目前的负载情形,然後将建立物件的要求转送到最不忙碌的机器。如本章前面所述,元件负载平衡只在Windows 2000的技术预览版本上才有提供,正式的版本中并未支援。</span><span  id=Layer50></li><br></font><font size=2 face=arial color=#3c3c3c><li><font size=2 face=arial color=#3e80d7><b>&nbsp;其它的服务</span><span  id=Layer51>&nbsp;</b></font>(</span><span  id=Layer52><font size=2 face=arial color=#3e80d7><b>&nbsp;Miscellaneous other services</span><span  id=Layer53>&nbsp;</b></font>) 包含了Bring Your Own Transaction (BYOT),允许你明确加入一个正在进行的交易之中,支援COM物件的建构者(constructor)等等。</span><span  id=Layer54></li><br></font></ul></font><p><font size=2 color=#3c3c3c face=arial>COM+所提供的大部份服务都是由增强版的COM runtime提供的。这个runtime是Windows 2000的标准部份,如图8-1所示。它介於COM物件与客户端之间,拦截客户端对COM物件所发出的每一个method call。不管客户端是否为一个执行在桌上型电脑,透过DCOM存取这些物件的Visual Basic程式,或是一支执行在与这些物件相同的机器上之ASP script,或其它的程式,由於介於客户端与客户端使用的COM物件之间,都允许COM runtime提供许多有用的服务。如图中所示,使用这些服务的物件大多是最常存取一个或多个资料库的。</span><span  id=Layer55></font></p><hr><font face=Arial Black color=#3e77d7 size=3><b></b></font><p><font size=2 color=#3c3c3c face=arial>COM+主要是透过增强版的COM runtime程式库来提供服务</span><span  id=Layer56></font></p><hr><br><center><a target=_new href=imagesh/8-1.gif><img border=0 src='imagesl/8-1.gif'></a></center></span><span  id=Layer57><center><table border=0 ><td align=center><font color=#3c3c3c face=arial size=2><font size=2 face=arial color=#3e80d7><b>&nbsp;图8-1</span><span  id=Layer58>&nbsp;</b></font>浏览器与非浏览器的客户端能更透过COM runtime存取COM物件。</span><span  id=Layer59></td></table></font></center><a name=208002><font color=#3e70d7 face=arial size=5><b>COM+基础概念</span><span  id=Layer60></b></font><p><font size=2 color=#3c3c3c face=arial>若要掌控COM runtime提供的服务首要工作便是了解一些其它的事情。在本章中,我将假设你至少已阅读过</span><span  id=Layer61>&nbsp;<a href=201.htm# target=_new>第一</span><span  id=Layer62></a>&nbsp;、</span><span  id=Layer63>&nbsp;<a href=205.htm# target=_new>五</span><span  id=Layer64></a>&nbsp;、</span><span  id=Layer65>&nbsp;<a href=206.htm# target=_new>六</span><span  id=Layer66></a>&nbsp;与</span><span  id=Layer67>&nbsp;<a href=207.htm# target=_new>七章</span><span  id=Layer68></a>&nbsp;的内容,因此你已了解Windows 2000分散式环境的基础概念,包含COM、ADO与DTC。在进一步了解COM runtime提供给应用程式使用的服务之前,还有许多的概念需要介绍。</span><span  id=Layer69></font></p><font color=#3e72d7 face=arial size=4><b>COM+ 应用程式</span><span  id=Layer70></b></font><p><font size=2 color=#3c3c3c face=arial>若要使用COM+,则商业逻辑必须撰写成一个或多个(通常是多个)in-process的COM元件,这也就是说,写成包装成DLL的COM类别。一旦这些元件建立後,便可使用元件服务(Component Services)管理工具将其分组成COM+应用程式。(所谓的COM+应用程式就是指MTS中所称的套件(package),不过不要被这个术语搞混了∶COM+应用程式只提供完整的叁层式应用程式之中间层。)在特定COM+应用程式中的所有元件都会执行在相同的行程中,因此将元件分组成应用程式的方式便决定行程的结构。</span><span  id=Layer71></font></p><hr><font face=Arial Black color=#3e77d7 size=3><b></b></font><p><font size=2 color=#3c3c3c face=arial>一个COM+应用程式是一组in-process的COM 元件</span><span  id=Layer72></font></p><hr><p><font size=2 color=#3c3c3c face=arial>两种最重要的COM+应用程式便是伺服器应用程式(Server Application)与程式库应用程式(Library Application)。这两个应用程式主要的不同点在於,每一个伺服器应用程式分别执行在自己的行程中,而从程式库应用程式中建立的元件将会执行在建立物件的客户端之行程内。如图8-2所示,对於单独的Windows 2000机器来说同时执行多个伺服器应用程式是完全合法的。每个伺服器应用程式将会执行在自己的行程中,而每个行程将会有自己的一份COM runtime复本。因为身为COM+应用程式的元件都必需是DLL,因此必需要有某个EXE档案,以提供一个行程让DLL执行。通常这个EXE的选择是随着Windows 2000出货的简单行程,称为COM+代理程序(COM+ Surrogate)。本章没有提供任何图片阐述代理程序,通常在EXE被要求宿驻(host)某些COM+应用程式的DLL时会自动地载入。</span><span  id=Layer73></font></p><hr><font face=Arial Black color=#3e77d7 size=3><b></b></font><p><font size=2 color=#3c3c3c face=arial>COM+支援伺服器应用程式与程式库应用程式</span><span  id=Layer74></font></p><hr><p><font size=2 color=#3c3c3c face=arial>在图中,Server Application 1包含元件A与B,已载入到同一个行程中,而客户端将可从COM runtime的其中一个实例 (instance)存取它的物件。Server Application 2包含元件C与 D已载入另一个行程,还有一个包含元件E与F的程式库应用程式已载入相同的行程中。有两个客户端呼叫其中一个应用程式或两个应用程式中的物件之method,所有的呼叫动作都会透过第二个行程中的COM runtime进行。</span><span  id=Layer75></font></p><br><center><a target=_new href=imagesh/8-2.gif><img border=0 src='imagesl/8-2.gif'></a></center></span><span  id=Layer76><center><table border=0 ><td align=center><font color=#3c3c3c face=arial size=2><font size=2 face=arial color=#3e80d7><b>&nbsp;图 8-2</span><span  id=Layer77>&nbsp;</b></font>每个COM+伺服器应用程式都拥有自己的行程,而程式库应用程式则否。</span><span  id=Layer78></td></table></font></center><p><font size=2 color=#3c3c3c face=arial>一旦一个COM元件成为COM+应用程式的一部份,这个元件就被视为一个已设定元件(configured component)。回顾一下在一个COM+应用程式中所有的元件都必需撰写成in-process伺服器,意思是每一个设定的元件都必需为一个DLL。在Windows 2000平台上,一个非隶属於COM+应用程式一部份的COM元件称为未设定元件(unconfigured component),也就是在</span><span  id=Layer79>&nbsp;<a href=205.htm# target=_new>第五章</span><span  id=Layer80></a>&nbsp;提及的部份。一个元件最多仅可以是一台特定机器上某个COM+应用程式的一部份,因此关於元件属於哪一个应用程式就不会暧昧不明了。</span><span  id=Layer81></font></p><hr><font face=Arial Black color=#3e77d7 size=3><b></b></font><p><font size=2 color=#3c3c3c face=arial>身为一个COM+ 应用程式一部份的元件称为已设定元件</span><span  id=Layer82></font></p><hr><p><font size=2 color=#3c3c3c face=arial>关於这两种元件的资讯是储存在它们所存在的机器上之系统登录中。对於已设定元件来说,额外的资讯将会储存到一个系统登录之外的资料库,称RegDB。关於系统登录中已设定元件与未设定元件的资讯,以及储存在RegDB中未设定元件的资讯则合称为COM+目录(COM+ Catalog)。在这个目录中的资讯可透过元件服务管理工具存取,它是一个MMC嵌入单元。或者也可以直接透过标准的COMAdminCatalog 实作之ICOMAdminCatalog介面存取。当一个客户端从一个已设定元件建立一个物件时,COM runtime便检查目录,得知关於物件的资讯,然後判断它需要哪些服务。运作的情况稍後再详述。</span><span  id=Layer83></font></p><font color=#3e72d7 face=arial size=4><b>COM+中物件建立的过程</span><span  id=Layer84></b></font><p><font size=2 color=#3c3c3c face=arial>对於在桌上型电脑上执行,并存取某些伺服器上已设定元件的客户端机器来说,COM runtime不留痕迹地提供它的服务,客户端不需为此进行某些特殊的动作。取代的作法,客户端仍照往常的方式建立一个COM物件,呼叫它的method,然後在不需要的时侯释放这个物件。COM runtime默默地提供物件所要求的服务。</span><span  id=Layer85></font></p><hr><font face=Arial Black color=#3e77d7 size=3><b></b></font><p><font size=2 color=#3c3c3c face=arial>客户端仍不会察觉COM runtime 提供给物件的服务</span><span  id=Layer86></font></p><hr><p><font size=2 color=#3c3c3c face=arial>不过COM runtime如何得知这些服务为何呢?答案是每个已设定元件都有一组特定的属性,大部份储存在RegDB。这些属性能够设定的值将在本章中讨论;现在要了解的重点是当物件建立时,COM runtime立即检视这些属性,然後依照这些属性为新物件建立适当的context。基於这个context的资讯,COM runtime便能判断物件需要的服务为何了。</span><span  id=Layer87></font></p><hr><font face=Arial Black color=#3e77d7 size=3><b></b></font><p><font size=2 color=#3c3c3c face=arial>一个已设定元件的属性会影响从那个元件建立的物件之context</span><span  id=Layer88></font></p><hr><p><font size=2 color=#3c3c3c face=arial>图8-3阐述一个简单的建立过程。在这个范例中,一个桌上型的客户端要求以标准的方式建立物件(就是所谓的启动),使用CoCreateInstance,或客户端的程式语言所用的任一个适当的呼叫动作。(这个范例假设一个DCOM客户端,若为一个Web客户端,则建立物件的呼叫必需由一个执行在Windows 2000伺服器机器上的ASP网页发行出来,以回应使用者经由HTTP 从浏览器发出来的要求。)虽然图中并未显示,客户端的要求会导致客户端机器上的COM runtime检查之前</span><span  id=Layer89>&nbsp;<a href=205.htm# target=_new>第五章</span><span  id=Layer90></a>&nbsp;所描述的系统登录,然後传送建立物件的要求到伺服器机器。</span><span  id=Layer91></font></p><hr><font face=Arial Black color=#3e77d7 size=3><b></b></font><p><font size=2 color=#3c3c3c face=arial>客户端可以如往常一样呼叫CoCreateIns-tance 从已设定元件建立物件</span><span  id=Layer92></font></p><hr><p><font size=2 color=#3c3c3c face=arial>接下来,伺服器机器上的COM runtime便会检查机器中COM+目录的CLSID_X。在此便可以找到关於这个CLSID所指的类别的许多丰富资讯。最基本的资讯是,它可以得知这个CLSID参考到一个已设定元件或是一个未设定元件。如</span><span  id=Layer93>&nbsp;<a href=205.htm# target=_new>第五章</span><span  id=Layer94></a>&nbsp;中所描述,若CLSID_X参考到一个未设定元件,则所有关於这个类别的资讯便储存在系统登录中。然而,假设CLSID_X参考到一个已设定元件,COM runtime便如同找寻未设定类别一样,从系统登录(Registry)找寻基本的资讯,其中包含这个类别的档案是哪一个。不过COM runtime同样会从RegDB搜寻已设定元件的许多相关资讯,包含了元件归属於哪一个COM+应用程式,以及曾设定了元件的各种属性之属性值...。有了所有的资讯,现在COM runtime就可以建立物件,确保它们在正确的行程中启动。COM runtime同样也会为物件在记忆体中建立适当的context,其中包含目录中这个类别的所有设定值。</span><span  id=Layer95></font></p><hr><font face=Arial Black color=#3e77d7 size=3><b></b></font><p><font size=2 color=#3c3c3c face=arial>物件的context会受COM+目录中物件类别的资讯所影响</span><span  id=Layer96></font></p><hr><br><center><a target=_new href=imagesh/8-3.gif><img border=0 src='imagesl/8-3.gif'></a></center></span><span  id=Layer97><center><table border=0 ><td align=center><font color=#3c3c3c face=arial size=2><font size=2 face=arial color=#3e80d7><b>&nbsp;图8-3</span><span  id=Layer98>&nbsp;</b></font>在启动的过程中,COM runtime检视物件设定的属性,然後为物件建立适当的context。</span><span  id=Layer99></td></table></font></center><p><font size=2 color=#3c3c3c face=arial>到目前为止,我们已知假设受COM runtime所管理的物件之建立者是一个没有Context的客户端。不过,再假设一旦这个简单的客户端已建立一个如先前描述的新COM物件,这个物件本身希望建立其它的物件。那麽现在会发生什麽事?</span><span  id=Layer100></font></p><p><font size=2 color=#3c3c3c face=arial>运作的过程看起来很类似。然而,如图8-4所展示,有些很重大的不同点。一如往常,执行的物件X可以发行一个CoCreateInstance,或使用的语言支援呼叫,然後COM runtime将会执行必要的步骤来建立这个物件。如图所示,runtime在COM+目录中查阅CLSID_Y,然後找寻这个类别的必要资讯,再用这些资讯正确地建立物件。</span><span  id=Layer101></font></p><p><font size=2 color=#3c3c3c face=arial>在这个情况下,物件的建立者已经拥有一个context,而其包含的资讯必在建立的过程中列入考虑。若新物件的属性与物件建立者的属性相容,新物件将不会建立新的context。取代的作法是,它将会与建立者共享context。若两个物件的需求中有任何的不同点(这是目前最常见的案例),COM runtime将会为新的物件建立新的context。当然,放置在新context的值将会继承自目录中所找到的资讯,以及物件建立者Context中的值。视许多外在因素影响,某些建立者的属性能够下传到新的物件。关於这些属性将会在本章稍後再阐述,不过目前已足够能了解一个物件建立另一个物件的时机为何,新物件的context包含从COM+目录,以及物件建立者的Context两者继承而来的。</span><span  id=Layer102></font></p><hr><font face=Arial Black color=#3e77d7 size=3><b></b></font><p><font size=2 color=#3c3c3c face=arial>一个物件的context可能包含了从它的建立者继承而来的资讯</span><span  id=Layer103></font></p><hr><p><font size=2 color=#3c3c3c face=arial>Context最後一个值得注意的是跨context的呼叫 (在同一个apartment中,且不同context的COM物件之间相互叫用method) 承担了一些负载。当stub与proxy用在不同的机器、不同的行程,或不同apartment之间的呼叫时,这两者并非必要的。共享apartment,但不共享context的物件之间相互叫用时,便利用了类似上述的软体,称轻量级的proxy。COM runtime自动地建立并使用这些proxy,因此一个程式设计师从来就不会看到它们。它们的存在仍旧代表着跨不同的context共享一个介面指标需要程式设计师的特别关照。</span><span  id=Layer104></font></p><hr><font face=Arial Black color=#3e77d7 size=3><b></b></font><p><font size=2 color=#3c3c3c face=arial>在不同的context中呼叫一个物件将会使用轻量级的proxy</span><span  id=Layer105></font></p><hr><hr><font face=Arial Black color=#3e77d7 size=3><b> 附注</b></font><p><font size=2 color=#3c3c3c face=arial>补捉拥有不同context的物件之间的呼叫就是所谓的拦截(interception)。Microsoft已经告诉某些人放宽拦截的机制,允许协力厂商的软体能插入呼叫路径中。不过在COM+ 1.0中这是不可能的。</span><span  id=Layer106></font></p><hr><br><center><a target=_new href=imagesh/8-4.gif><img border=0 src='imagesl/8-4.gif'></a></center></span><span  id=Layer107><center><table border=0 ><td align=center><font color=#3c3c3c face=arial size=2><font size=2 face=arial color=#3e80d7><b>&nbsp;图8-4</span><span  id=Layer108>&nbsp;</b></font>当一个物件建立另一个物件时,新物件可以继承物件建立者的context或与物件建立者共享。</span><span  id=Layer109></td></table></font></center><font color=#3e72d7 face=arial size=4><b>存取Context资讯</span><span  id=Layer110></b></font><p><font size=2 color=#3c3c3c face=arial>事实上受COM runtime管理的每一个物件都需要与它的context以及runtime本身的context进行互动。为了达到这个目的,COM runtime显露许多不同的介面,每个介面包含的method允许一个执行中的物件能和它的Context资讯一起运作。在这之中的是IObjectContext,这个介面最早是由已经走向历史的MTS Executive提供的。COM+整修IObjectContext所提供的函数,增加了其它的介面,提供相同的method,不过以不同的方式进行分组,然後再加上一些新特性。这些新介面包含了IObjectContextInfo、ISecurityCallContext、与IContextState,稍後在本章中介绍。有些人争论着既然新介面已大量取代了IObjectContext所提供的服务,新的应用程式应该使用新介面而不要使用旧介面。不过IObjectContext仍旧是存取COM+核心服务最简单的方式,因此在大部份的讨论中,我将假设使用这个传统的介面。</span><span  id=Layer111></font></p><hr><font face=Arial Black color=#3e77d7 size=3><b></b></font><p><font size=2 color=#3c3c3c face=arial>物件存取他们的context要透过IObject-Context 与其它介面</span><span  id=Layer112></font></p><hr><hr><font face=Arial Black color=#3e77d7 size=3><b> 附注</b></font><p><font size=2 color=#3c3c3c face=arial>其中一个例外情形是IObjectContext's CreateInstance method。这个method对MTS来说是相当重要的,它是MTS物件用来建立另一个物件的唯一方式。今日,虽然它仍旧可以运作,不过IObjectContext::CreateInstance是相当庞大的旧式方案。目前,COM物件可以用标准的CoCreateInstance呼叫来建立其它的COM物件。</span><span  id=Layer113></font></p><hr><p><font size=2 color=#3c3c3c face=arial>若要呼叫IObjectContext中的method,物件必需要先取得这个介面的指标。IObjectContext是实作在ObjectContext物件中(有时称为context物件)。如图8-5所示,若要取得IObjectContext的介面指标,COM物件可以呼叫GetObjectContext (在Visual Basic中) 或CoGetObjectContext (在C++中),它们是COM runtime所提供的API函数。一旦拥有这个指标,物件就可以呼叫IObjectContext的method,以便使用COM runtime所提供的许多服务。其中一个重要的服务便是自动交易处理,也就是下一个主题。</span><span  id=Layer114></font></p><hr><font face=Arial Black color=#3e77d7 size=3><b></b></font><p><font size=2 color=#3c3c3c face=arial>物件呼叫CoGetObject-Context以取得IObjectCon-text的指标</span><span  id=Layer115></font></p><hr><a name=208003><font color=#3e70d7 face=arial size=5><b>自动交易处理</span><span  id=Layer116></b></font><p><font size=2 color=#3c3c3c face=arial>如</span><span  id=Layer117>&nbsp;<a href=207.htm# target=_new>前章</span><span  id=Layer118></a>&nbsp;所描述,交易的all-or-nothing行为通常需要实践一个商业程序。当在一个DBMS中无法使用ADO控制交易时,或者无法直接使用DTC管理分散式交易时,COM+提供其它的解决方案,使其更容易、更适用在叁层式应用程式上∶自动交易处理。在背後,COM_自动交易处理依赖於DTC,若牵涉到DBMS,则也得依赖DBMS交易管理员(transaction manager) 的功能。不过自动交易处理比起这些解决方案的任一种,提供了更多重要的优点。</span><span  id=Layer119></font></p><br><center><a target=_new href=imagesh/8-5.gif><img border=0 src='imagesl/8-5.gif'></a></center></span><span  id=Layer120><center><table border=0 ><td align=center><font color=#3c3c3c face=arial size=2><font size=2 face=arial color=#3e80d7><b>&nbsp;图8-5</span><span  id=Layer121>&nbsp;</b></font>物件可以呼叫CoGetObjectContext,以便获得指向它的ObjectContext之IObjectContext介面指标。</span><span  id=Layer122></td></table></font></center><p><font size=2 color=#3c3c3c face=arial>首先,自动交易处理很容易使用。一旦应用程式的设计师与程式开发者了解它们如何运作时,建立使用自动交易处理的元件便非常容易了。第二,从独立的元件使用自动交易处理时,运作的过程相当良好。他们允许你在部署单一的元件时可以以不同的方式进行,也允许部署到不同的应用程式,然後仍旧可以得到自己要求的交易行为。程式设计师可以建立一个交易性元件,只做一件事,且可以做得很好,然後可能在许多的情况中使用之。重复使用商业逻辑本来就是一件相当困难的事,而COM+提供的自动交易处理则扫除障碍,直达成功大门。</span><span  id=Layer123></font></p><hr><font face=Arial Black color=#3e77d7 size=3><b></b></font><p><font size=2 color=#3c3c3c face=arial>自动交易处理相当简单且容易使用</span><span  id=Layer124></font></p><hr><font color=#3e72d7 face=arial size=4><b>自动交易处理运作的情形</span><span  id=Layer125></b></font><p><font size=2 color=#3c3c3c face=arial>若要了解自动交易处理运作的情形,回想</span><span  id=Layer126>&nbsp;<a href=207.htm# target=_new>前章</span><span  id=Layer127></a>&nbsp;介绍的DTC范例。在这个范例中,一个DTC客户端从储存在SQL Server资料库的存款帐号进行转帐,将帐款转到储存到Oracle资料库的支票户头。透过DTC确保两方的更新动作都会成功地执行,或都不执行。透过COM+,程式设计师能够完成同样的动作,而甚至不需察觉DTC的存在。取代的方式是,COM物件的建立者可以实作一个method,假设称为MoveMoney,这个method接受叁个参数∶Source,是欲扣款的银行帐户;Target,是欲存入的银行帐户;以及Amount,是欲转帐的金额。这个物件的客户端便可呼叫MoveMoney method,传入适当的值,进行转帐的动作。透过这几个简单的动作,method的实作者可以使用COM+的自动交易处理机制来确保两个查询都能成功,或同时失败。</span><span  id=Layer128></font></p><hr><font face=Arial Black color=#3e77d7 size=3><b></b></font><p><font size=2 color=#3c3c3c face=arial>自动交易处理让程式设计师不用面对DTC</span><span  id=Layer129></font></p><hr><p><font size=2 color=#3c3c3c face=arial>图8-6显示程序中的第一个步骤。在第一个步骤中,客户端呼叫MoveMoney method。(图中建议客户端是一个远端的系统,透过DCOM进行呼叫,不过客户端最好是一个ASP网页,执行在和实作这个method的COM物件所在的同一台电脑上。)因为被呼叫的物件设定为使用自动交易处理机制,这个method call将会被COM runtime拦截,如步骤二所示,runtime检视物件的context资讯以便判断是否要开启一个新交易。(元件如何进行组态设定的动作将会简短地说明。)在这个范例中,物件确实需要交易处理机制,因此COM runtime使用OLE Transactions告知DTC开始一个新交易。</span><span  id=Layer130></font></p><hr><font face=Arial Black color=#3e77d7 size=3><b></b></font><p><font size=2 color=#3c3c3c face=arial>当呼叫物件的一个method时,C O M runtime能自动开始一个新交易</span><span  id=Layer131></font></p><hr><hr><font face=Arial Black color=#3e77d7 size=3><b> 附注</b></font><p><font size=2 color=#3c3c3c face=arial>这个动作有点简单化的意味。事实上,COM runtime延迟交易的进行,直到它确认物件确实需要交易,如物件发行一个资料库查询时。</span><span  id=Layer132></font></p><hr><p><font size=2 color=#3c3c3c face=arial>然後COM runtime允许method call继续执行,并呼叫COM物件的程式设计师实作出来的MoveMoney。这个method开始执行,如图步骤叁所示,接着发行第一个SQL查询,指示SQL Server减去特定存款帐户的金额。就如同</span><span  id=Layer133>&nbsp;<a href=207.htm# target=_new>前章</span><span  id=Layer134></a>&nbsp;讨论的DTC一样,SQL Server将会加入活动中的DTC交易之中,然後执行这个查询,如步骤四所示。</span><span  id=Layer135></font></p><hr><font face=Arial Black color=#3e77d7 size=3><b></b></font><p><font size=2 color=#3c3c3c face=arial>资源管理者会自动加入交易之中</span><span  id=Layer136></font></p><hr><p><font size=2 color=#3c3c3c face=arial>为要让这些图尽可能清楚些,我省略一些DTC的细节。然而,了解DTC之交互作用恰如</span><span  id=Layer137>&nbsp;<a href=207.htm# target=_new>前章</span><span  id=Layer138></a>&nbsp;所述。同样地,虽然在这个范例中使用OLE DB provider存取DBMS,COM物件最常用的介面还是ADO。</span><span  id=Layer139></font></p><a name="8-6"></span><span  id=Layer140><br><center><a target=_new href=imagesh/8-6.gif><img border=0 src='imagesl/8-6.gif'></a></center></span><span  id=Layer141><center><table border=0 ><td align=center><font color=#3c3c3c face=arial size=2><font size=2 face=arial color=#3e80d7><b>&nbsp;图8-6</span><span  id=Layer142>&nbsp;</b></font>客户端的method call会导致COM runtime开始一个交易,然後发行第一个查询,并将SQL Server加入这个交易中。</span><span  id=Layer143></td></table></font></center><p><font size=2 color=#3c3c3c face=arial>接下来如图8-7的步骤五所示,COM物件中的MoveMoney method发行它的第二个SQL查询,这次把目标放在Oracle资料库上,指定欲新增到支票帐户的金额。再次强调资料库将会加入交易之中,如步骤六所示,然後执行查询。</span><span  id=Layer144></font></p><p><font size=2 color=#3c3c3c face=arial>一旦两个查询皆执行後,MoveMoney method可以通知COM runtime已完成工作了。有两种可能的结果:全部成功执行,因此method希望能够确认交易中所有的工作;或者是某些动作执行失败,这表示method希望能够复原交易中所有的动作。(举例来说,或许帐户中并没有足够的金额可供扣款以满足这个需求,或者因为网路故障,而使得对Oracle资料库发出的要求不能成功执行。 )在任一种情况下,MoveMoney可呼叫IObjectContext的method,以通知COM runtime所希望的结果。如图8-8中的步骤七所示。若它希望确认这个交易,则呼叫IObjectContext::SetComplete,若希望取消这个交易则呼叫IObjectContext::SetAbort。</span><span  id=Layer145></font></p><hr><font face=Arial Black color=#3e77d7 size=3><b></b></font><p><font size=2 color=#3c3c3c face=arial>当它的工作完成後,一个交易性物件可以呼叫SetCom-plete或者是SetAbort</span><span  id=Layer146></font></p><hr><p><font size=2 color=#3c3c3c face=arial>如步骤八所示,COM runtime适当地回应。若物件呼叫SetComplete,则使用OLE Transactions通知DTC确认这个交易,OLE Transactions,而SetAbort则会告诉DTC取消这个交易。(注意这是一个简单的范例,交易中只包含一个单一的物件。当交易中包含多个元件时,就变得复杂多了。)在步骤九,DTC使用二阶段交付(two-phase commit)实行了COM runtime的要求,如</span><span  id=Layer147>&nbsp;<a href=207.htm# target=_new>前章</span><span  id=Layer148></a>&nbsp;所描述的一样。</span><span  id=Layer149></font></p><hr><font face=Arial Black color=#3e77d7 size=3><b></b></font><p><font size=2 color=#3c3c3c face=arial>COM runtime 告诉DTC确认一个交易或取消一个交易</span><span  id=Layer150></font></p><hr><br><center><a target=_new href=imagesh/8-7.gif><img border=0 src='imagesl/8-7.gif'></a></center></span><span  id=Layer151><center><table border=0 ><td align=center><font color=#3c3c3c face=arial size=2><font size=2 face=arial color=#3e80d7><b>&nbsp;图8-7</span><span  id=Layer152>&nbsp;</b></font>发行第二个查循将Oracle加入这个交易中。</span><span  id=Layer153></td></table></font></center><p><font size=2 color=#3c3c3c face=arial>最後,一旦所有的动作完成,同时交易结束後,MoveMoney method便回到它的呼叫者,如步骤十所示。呼叫者完全没有察觉它的复杂性,它只知道要求一个COM物件进行转帐的动作。实际上牵涉到交易的动作,呼叫者不会直接看到。</span><span  id=Layer154></font></p><a name="8-8"></span><span  id=Layer155><br><center><a target=_new href=imagesh/8-8.gif><img border=0 src='imagesl/8-8.gif'></a></center></span><span  id=Layer156><center><table border=0 ><td align=center><font color=#3c3c3c face=arial size=2><font size=2 face=arial color=#3e80d7><b>&nbsp;图8-8</span><span  id=Layer157>&nbsp;</b></font>为了结束交易,MoveMoney method呼叫SetComplete或SetAbort,而COM runtime将会与DTC一起运作以完成这个要求。</span><span  id=Layer158></td></table></font></center><p><font size=2 color=#3c3c3c face=arial>为了协助你对这个范例的动作拥有较清楚的概念图,以下是一个简单的虚拟码,描述MoveMoney method所做的事:</span><span  id=Layer159></font></p><div style="background-color: #D7D7D7;"><font face=Arial size=3><pre>MoveMoney(Source,Target,Amount)   对SQL Sverver发行一个SQL查询,从资料来源减去金额(Amount)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -