不能停止的COM+组件(100分)

  • 主题发起人 主题发起人 Sachow
  • 开始时间 开始时间
S

Sachow

Unregistered / Unconfirmed
GUEST, unregistred user!
去年下半年做了一个系统,采用的是COM+技术,应用服务器用BDE + Oracle 8.1.6客户端连接Oracle 7.3.4数据库,现在遇到的问题是应用服务器组件一旦启动就再也无法停下来。
我们知道,在COM+组件服务中有一项选项,即“闲置关闭之前的时间”,我在其中只设了三分钟,如果组件的引用计数为零并达到3分钟时间,dllhost就会释放组件。但是现在组件总是得不到释放,其结果导致当组件运行到一定时间(比如两个星期)后,就会开始变得不稳定,直至最后无法服务。
导致组件不能释放的原因我估计是由于有客户端调用没有释放,但我的组件是由ASP调用的,在一个页面处理完成后,就会超出对象的作用范围,此引用计数就会撤消,因此应该不存在做为客户端的ASP没有释放引用计数的问题。我另外有一种用于处理报表的COM客户端程序,采用TSocketConnection连接服务器,但我在Borland Socket Server中设置了超时,当客户端闲置达到一定时间时主动断开客户端,因此也应该不是由于某些报表客户端程序没有关闭而导致组件不能释放。
那是什么原因导致组件不能释放呢?异常?
我注意到,当系统运行没有遇到异常发生的时候,是会自动释放的,但当遇到异常后,就会出现这个问题,难道是由于异常对象没有被释放导致的?那又该怎么处理异常为好呢?
在发生异常时,为了可以分析导致异常的原因,不能简单地用捕获异常的方式将异常信息屏蔽,而是要将异常信息传给客户端,从而使客户端界面上可以反映出异常信息来。我目前采用的是(CB代码,Delphi高手可以以Delphi的角度进行分析):
return Error(WideString(E.Message), IID_IiPAS_AppServer);
这是使用ATL的方式,在组件方法发生异常时将异常传递给调用者,是不是问题出在这里呢?
(先发100分,问题解决后再开个200分的贴以酬谢)
 
建议采用这种格式书写
try
...
SetComplete;
except
SetAbort;
end;
这样可以保证出错时释放掉组件
 
我已经将事务类型设为“支持事务”,并且自己处理事务逻辑,因此,SetComplete()和SetAbort()应该不会有什么作用。
 
很头疼,好象很多人都有碰到过这方面的问题,但总没有好的解决办法。
提个建议,用COM+的时候不要用BDE,用ADO试试看。都用MS的可能会好点:)
 
有一种可能,是你的程序在某个地方弹出了异常提示窗口,等待你去点。
当然,那个窗口是看不到的。
 
我也有同样问题,各位大侠请帮忙吧,
我的mail:lillin@21cn.com
 
我认为:
  1、COM+中应该用ADO,因为BDE天生“讨厌”COM+(无法很好实现ObjectContectex)
  2、COM+中事务应该尽量让COM+自行决定,如果非要自己决定,请先判定此组件是否正处于事务中,而且应该先取得IObjectContectex后再设置事务,不要在SQL语句中设置,并必须象xujh说的那样进行SetComplete或SetAbort操作。
  3、COM+中如果有给网页调用的组件,不要直接把逻辑编写在ASP组件中,因为ASP组件不是真正的COM+组件,应该用ASP组件调用COM+的协调组件,这样才不会出问题。
  4、建议你看看李维的《Delphi 5.X ADO_MTS_COM+高级程序设计篇》
一些粗见,欢迎批评指正。
 
以前用Oracle 9i数据库做过一个类似结构的系统,运行起来很稳定,但现在这个的情况则大为不同,让人感到很不解。
我觉得比较头痛的地方是李维的例子都是基于SQL Server数据库的,而在用Oracle时,一些不会出现在SQL Server中的状况就会频繁发生,特别是在我取得8.1.7.4 Patch Set之前,除了用BDE存取并直接处理事务外没有其它选择,前不久得到了Patch Set,经试验发现可以用在COM+中用ADO正常存取了(除了不支持中文字段名以外),但程序框架已经写成,要改的话得花不少的时间,只有等忙完眼前这一头才能考虑改动了。
 
后退
顶部