COM+对象的单实例多线程问题。(300分)

  • 主题发起人 主题发起人 沙隆巴斯的主人
  • 开始时间 开始时间

沙隆巴斯的主人

Unregistered / Unconfirmed
GUEST, unregistred user!
在我手头的一个应用中,有多个客户端(<=30),其主要业务是一些典型的事务型处理。由于业务强度和预算都不大,因此最后采用了在WINDOWS上的解决方案:DELPHI在MTS(COM+)上的开发。
我的中间服务器采用COM+(ActiveX Library + Transaction Object)
在这个COM+对象里包含一系列的资源、对象:数据库连接(池),用户对象(池),商品种类(池)。。。。这些资源在COM+对象被建立(激活)时候从数据库和外部配置文件中取得(这是个大开销的过程),此后,这些资源、对象就被缓存在各个池中以供后需(当然,还有对资源的清理过程,当发现某资源、对象长时间未被使用或某资源长时间被占用的话,会对其进行释放或剥夺等)。很显然,这些资源应该仅在服务器中保存一个实例(出于资源效率和一致性、完整性的考虑)并且常驻内存,因此,这个COM+应该是单实例多线程的(已经有代码保证临界资源的访问安全以及事务处理了)。
现在的问题是:在建立Transaction Object的Wizard中没有关于instance的选项,那么,该如何控制COM+使它满足我的要求?
 
就达到你的要求而言,你只要将如下代码中的ciMultiInstance改为ciSingleInstance就可以了.
initialization
TAutoObjectFactory.Create(ComServer, Taaa, Class_aaa,
ciMultiInstance, tmApartment);
end.
 
to smokingroom:
首先,谢谢你的回答。
按照你提示的方法,修改了initialization中
TAutoObjectFactory.Create(ComServer, Taaa, Class_aaa,
ciMultiInstance, tmApartment);
的后两个参数(一共15种组合),进行了测试
我在COM+对象里实现了一个
function TTest.getAddress: WideString;
begin
Result := IntToStr(Integer(Pointer(Self)));
end;
方法。它返回当前对象的地址。
在客户端,我建立了多个COM+的对象,取其地址,发现都是不一样的,说明有多个COM+对象的实例被创建。
因此,你提示的方法是不成功的。
 
尝试不要使用Transactional DataModule向导建立程序,而使用Automation Object向导建立程序,然后手动建立一个普通的数据模块,数据模块的实例化代码在ActiveX Library DLL的初始化代码码中执行,而不是在这个Automation Object的构造函数中执行(以保证数据库模块只有一个实例)。
我觉得这样做没有什么必要,在采用Transactional DataModule向导建立的Apartment线程模型的组件中,是不需要自己费工夫来做线程同步方面的处理的。
 
to Sachow:
很感谢你的回帖。
其实今天下午已经找到办法实现我的要求了,方法与你的接近。
1、将资源池声明为一个全局变量;
2、在initialization中实例化它(仅一次)
3、每个COM+对象都可以访问此资源池
实际上没个COM+对象在这的脚色类似于一个SESSION BEAN,而资源池则是ENTITY BEAN容器
 
问题虽然解决了,但继续保留此帖一周,希望有熟悉COM+生命周期的FW能够对COM+对象的动态物理特性继续发表见解。关于这方面的资料能够找到的不多。
另,TO Sachow:
Apartment可以能够提供的线程内的LOCAL安全保障,实现可重入,但对线程间共享的资源的访问控制,它是无能为力的。
 
看到好贴子,顶一下,无论是提问还是回答,都是不错的:)
 
缓冲放在
SharedPropertyGroup
也是一法
 
其实今天下午已经找到办法实现我的要求了,方法与你的接近。
1、将资源池声明为一个全局变量;
2、在initialization中实例化它(仅一次)
3、每个COM+对象都可以访问此资源池
实际上没个COM+对象在这的脚色类似于一个SESSION BEAN,而资源池则是ENTITY BEAN容器
我在我的三层应用中的连接池也是这样实现的。其实Delphi的应用服务器的线程池的例子明
确了这一点,就是连接池是全局变量的,而不是在Com+对象内部的实例,当然访问全局对象池时需要使用信号机和临界来解决冲突的问题。我个人觉得Delphi的那个连接池虽然简单
但是却非常清楚。
 
楼上解决的说明白一点,我被这个问题困扰几天了。我的实现时把所有的
需要的共享的资源都封装到了一个DataModule中了,(我做的是一个进程外
Dcom服务器)目前的问题是,在客户创建实例的时候,在同一个机器上启动的都是
应用服务器的单实例,无论起对少客户实例(这里估计使用了引用计数),
但在不同的机器上(客户不同,ip不同),服务端的就是多实例,具体就是每一个
客户机都启动了一个属于本机的应用实列,而我希望的是无论有多少对象实例及其任何分布,他们都能共享一个应用实列,例如:ComApp在A服务器,则A服务器上的所有实例都可以共享DataModule,但B客户机一旦创建该服务,必然会有一新应用服务实例被创建,C机则会有第三个.....这些机器上的DataModul也是打死不相往来。楼上说的方法我全都试过,问题依旧,不知道你们是怎么的搞定的,俺的qq249008105,希望老乡们多帮帮忙
 
我會寫一點c/S﹐今天才接觸 "池" 這個概念﹐我想問一個問題﹕
所謂池﹐是不是在中間里設的一個"TRemoteDataModule" ,而這些"池"的代碼是寫在"TRemoteDataModule"里﹐還是再開一個"unit"寫呢﹖要是再開一個"unit"寫﹐那
這個unit和TRemoteDataModule又是怎樣連接呢﹖
再請問﹐李維的偽三 層和真正的三有什么區別呢﹖
能不能給個例子給我們大家看看﹖
謝謝﹗
 
安裝目錄下自帶例子都別好
Delphi6/Demos/Midas/AdHoc
 
多人接受答案了。
 
后退
顶部