zoukankan      html  css  js  c++  java
  • 用Delphi 编写Com+的心得体会.

    相关名词:

      (1) idispatch是COM object的接口, 在Delphi中通常指一个OleObject. 

      (2) OleVariant是一种COM object兼容的Variant类型, 可以通用任何Ole Automation 类型, 他与CreateOleObject创建的idispatch兼容 

    1:Com+的编写: 

       1:File---->New---->Other....---->ActiveX Library 标签 下的 Transactional Object 

       2: 然后填写: CoClss Name :类的名字,比如:ComPlus Threading Modal :线程模式:Apartment 选项: Supports transactions 

       3:然后在View--->Library的对话框中增加方法 注意:如果参数为输出的话,则类型要是指针型,比如:Long * ,然后修改后面的参数in :out,ret 

       4:最后完善增加的方法就ok了

    2:客户端调用的编写: 

       1:先倒入Com+的接口类型. Project --->import Type Library---->选中你编写的Com+的类型,然后选择:Create Unit 

    3、安装COM+组件有两种方式,

       第一种(推荐):如果是在IDE环境里,点击“Run->Install COM+ Objects”即可把打开的Active Library项目安装到COM+环境中,注意:如果打开的项目是 一个普通的Application项目,是不能被安装到COM+环境中的。 将要安装的com+打上勾,然后在application中有两个选项:install to existing application :表示你的com+安装在com服务器的哪个组件包中, install to New application:表示将当前com+组件安装到一个新的组件包中. 

       第二种办法:打开控制面板-> 管理工具->组件服务->计算机->我的电脑->COM+应用程序,在COM+应用程序的树项上点击 鼠标右键,选择“新建->应用程序”->创建一个空的应用程序,并为此应用程序命名,接下 来点击“下一步”直到结束即可。建立了空的COM+应用程序后,接下来就是把COM DLL安装 到COM+应用程序中了。在刚建立的空应用程序的树项中新建一个组件,选择“安装新组件”, 在打开文件对话框中选择要安装到COM+环境中的DLL文件,之后跟着向导做都可以了,要把 多个COM DLL安装到同一个COM+应用程序包中,只需重复以上步骤即可。

    4、“导出客户端组件包”指的是把已经注册的组件导出为.msi格式的文件,这些文件在客 户端安装后,只会在客户端注册组件,而不会安装多余的文件。如果不在客户端注册组件, 是不不能调用位于服务器上的组件的(此指服务器和客户端分布在不同的机器上时)。

    5:调试Com+程序 ---ok

        1.打开Windows中的组件管理,找到要调试的组件包,点右键,选择属性,在高级这页里选择调试选项,打勾; 然后在下面的调试路径中找到/processID:{xxxxxxxxxxxxxxxxxxxxxxxxxxxxx} 复制出来 

       2.在dephi中Run | Parameters… HOST APPLICATION 填入 {系统路径}/system32/dllhost.exe PARAMETERS 粘巾 /processID:{xxxxxxxxxxxxxxxxxxxxxxxxxxxxx} 

       3。很关键的一点:组件程序:project|option|linker|Include TD32 debug info 和Include remote debug symbols打勾 

       4.启动delphi,运行要调试的Com+程序,设置断点,然后运行客户端程序即可进入到Com+断点. 

       5.调试完后记得要在 Windows中的组件管理中的高级这页里调试选项勾去掉哟. 

    6:Com+需要注意的地方: 

       1:客户机运行就会报 interface not supported 错误 大致原因:轻舞肥羊 (2004-05-09 11:00:01) COM+的权限依赖于Windows的权限配置,在服务器需要有客户机的用户名和密码。 如果还不行,就在服务器上重新安装com+,重新导出.

        2:建立工程时,com+不能包含在工程组中.(我的实践) 

       3:COM+不支持Oracle吗?在用事务的时候出错:Using Oracle with Microsoft Transaction Server and COM+ 

    7:在Com+中添加远程数据模块 

       1:File---->New---->Other....---->Multitier 标签 下的 Transactional Data Module 

       2:然后在View--->Library的对话框中增加方法. 

    8:Com+中传递数组 

        先定义数组: type TDataRecord = record A: Byte; B: LongWord; C: Word; D: LongWord; end; 1:server: function GetData: OleVariant; var P: Pointer; begin VarClear(Result);//不知D5有没。 try Result := VarArrayCreate([0, SizeOf(TDataType)], varByte); P := VarArrayLock(Result); //Data: TDataType为你要传的记录类型 Move(Data, P^, SizeOf(TDataType)); finally VarArrayUnLock(Result); end; end; 2:Client procedure GetFile(const FileName: string); var P: Pointer; V: OleVariant; Data: TDataType; begin FillChar(Data, SizeOf(Data), 0); V := SocketConnection1.AppServer.GetData; try P := VarArrayLock(V); Move(P^, Data, SizeOf(Data)); finally VarArrayUnLock(V); end; end; 9:Com+中传递记录集 下面xeen 实验成功 uses ADOInt******************************************************************************************* 可以;你可以将ADO的数据作为一个Variant类型的变量进行传送:adodataset1.RecordSet这是原生的ado数据 这是服务端的一个方法的代码:把CodeSet的类型改为Variant*[in,out] function TADORec.getData: OleVariant; begin AdoDataSet1.Open; result := adodataset1.RecordSet; end; ************************************************************************************************************************ 客户端 uses adoint; var MyRecordset :_recordset; begin MyRecordset := IUnknown(CodeSet) as _recordset ************************************************************************************************************************** Com基本概念: 

       1:COM是一个基于二进制的标准。打个比方,我们用Delphi实现了一个对象,一般情况下,我们只能在Delphi来生成这个对象的实例并调用,而如果我们用Delphi实现了一个COM对象的话,我们可以用VC、VB或者其他任何一种支持COM对象的语言来生成实例和调用。反过来也一样,我们可以在Delphi中使用各种COM对象,而不用介意它是用什么语言编写的。COM提供了分布式COM对象的机制,形象地说你可以调用另一台机器中的COM对象。COM+则是MTS的一个升级,在COM的基础上进一步提供了事务处理和其他很多Pool技术。 

       2:线程模式:Apartment:多个线程服务. 

       3:当建立Com+时选择的事务模式为Requires a Transaction,Com+会根据客户的的请求建立相应的事务,不仅仅时数据库,还会有系统资源等事务.成功SetComplete.回滚SetAbort. 选择Requires a Transaction表示当用户调用这个COM+组件时,COM+环境会为这个组件建立一个新的事务上下文,这和数据库的事务不是一回事。当你的COM+组件提交数据时如果出错,应该告诉事务上下文,只要调用COM+组件的SetAbort方法就可以。这样一来,处于同一个事务上下文的所有COM+组件都会Rollback。如果数据提交成功,应该调用SetComplete,不调用这个方法也可以,因为在默认情况下,COM+组件的事务状态设置为EnableCommite。当处于同一事务上下文的所有COM+组件对象都调用了SetComplete时,该事务上下文才会真正的向数据库提交数据。 

       4:SetAbort合SetComplete是否正确调用 

       5:(阿朱) 建议:多个DLL在一个包,一个DLL中的COM公用一个ADOCONNECTION 6:问题:我已经在Transactional Data Module的Pooled属性里面设置了True了,但是在Win2000的组件服务管理的“组件属性”的“激活”一栏里面,仍然无法打开“启用对象共用”的选项 --->您可以将线程模式设置为tmNeutral或者tmBoth都可以。

    Com有需要研究和有疑问的地方: 

       1:Com+的模式: 

       2:到Com+的资源Pooling机制 

        3:用delphi6 开发Com+,用Neutral模式,尽量用Object Pooling,当然就是要无状态了,事务要尽量短,避免死锁,用ADO不要用BDe.Dbexpress等. 

       4:我的做法是,按功能划分组件,把查询和更新分为两个功能组件,因为查询不需要事务,所以只要支持事务就行了。更新一般需要事务 

       5:COM+的事务属性 COM+的事务默认级别是序列 Read,而不是我们认为的commit Read,而且我们设置AdoConnection的隔离级是不 管用的,只能强制用显式的SQL才能起效果。 例如: 一个中间层COM select * from a where py_code like 'S%' 继续下面有很多代码 另一个中间层COM update a set py_code=py_code where py_code like 'B%' 这时这个COM将会死锁等待,虽然改动的不是一个数据也会死锁 用Commit Read 或UnCommit Read不会 建议: 所以被多个子系统更新或读的表,要在最后打开和更新,不要早。另外可以强制改变ADOCONNECTION的隔离级

        6:Com+中如何进行事务处理??? 在COM+中,如何使用SetComplete和SetAbort进行事务管理?? 老兄,SetComplete和SetAbort怎么能在客户端调用呢?这样肯定是不行的。要保证事务,就在服务器端声明一个专门保存的接口方法,例如: procedure UpdateMyData(var AData1, AData2: OleVariant; var AMaxError, AErrorCount: Integer); begin try DataSetProvider1.Data := AData1; DataSetProvider1.ApplyUpdate(AMaxError, AErrorCount); DataSetProvider2.Data := AData2; DataSetProvider2.ApplyUpdate(AMaxError, AErrorCount); SetComplete; except SetAbort; end; end; 

       7:,在组件管理器中的“事务列表”里也看不到事务(应该有事务的时候),怎么看? 

       8:Com+的两大研究:事务 和 pooling 

       9:做一个提交用的COM+对象和一个协调用的COM+对象 ???

    谢祥选【小宇飞刀(xieyunc)】
  • 相关阅读:
    Struts2+Spring3+Mybatis3开发环境搭建
    spring+struts2+mybatis
    【LeetCode】Populating Next Right Pointers in Each Node
    【LeetCode】Remove Duplicates from Sorted Array
    【LeetCode】Remove Duplicates from Sorted Array II
    【LeetCode】Binary Tree Inorder Traversal
    【LeetCode】Merge Two Sorted Lists
    【LeetCode】Reverse Integer
    【LeetCode】Same Tree
    【LeetCode】Maximum Depth of Binary Tree
  • 原文地址:https://www.cnblogs.com/xieyunc/p/9126646.html
Copyright © 2011-2022 走看看