相关链接
http://expert.csdn.net/Expert/topic/1310/1310645.xml?temp=.9054834
http://expert.csdn.net/Expert/topic/1418/1418217.xml?temp=.5763056
一直以来,我在组件的模块中通过override父类中的Initialize和Destroy两个方法来进行模块的初始化和扫尾工作,可是在池化时发现事务不回滚的情况,其后经过文兄提醒,找到了父类中另外两个函数OnActivate和OnDeactivate,将初始化和扫尾的一些工作放在这两个函数中进行,于是问题解决。
今天偶然看书时,看到事务在回滚时要释放所拥有的所有资源,而在以前,释放资源的工作是在模块的Destroy中进行,而池化时由于放在的缓冲池中,于是Destroy函数并未执行,因此出现不回滚的问题,而池化过程中激发的是OnActivate和OnDeactivate两个事件,在此提醒笑天兄和关心此问题的兄弟们注意:)
各位兄弟还有什么高见,或者自己的经验教训,欢迎帖出,大家参考。20分莫嫌少,可以加到200di:)

解决方案 »

  1.   

    谢谢苹果,我一般用translation datamodule写com+组件,经文兄提醒后,直接在其OnActivate和OnDeactivate事件中处理初始化和资源释放,问题就可解决了。
      

  2.   

    alphax(多喝了三五杯):呵呵,要拿分,你也得写些经验啊,省得我们这些菜鸟们绕圈子啦:)
      

  3.   

    请问你们在OnActivate和OnDeactivate事件中都做了哪些工作?
      

  4.   

    在OnActivate中申请接口,OnDeactivate中将所申请的接口释放,为的是让所调用的接口提交或回滚所拥有的事务
    另外在有数据库连接的组件中,在OnActivate中连接数据库,在OnDeactivate中断开数据库连接。
    暂时用到这么多,可能还有其它的用处吧。
      

  5.   

    呵呵,这个问题其实李维的书已经讲过了。 Delphi 中 MTS\COM+ 对象的 OnActivate 事件和 IObjectControl 的 Activate 方法是连接在一起的;OnDeactivate 和 IObjectControl 的 Deactivate 方法联系在一起。而 IObjectControl 接口主要是让 MTS\COM+ 执行环境通知 MTS\COM+ 对象即将进入哪一个生命周期。在这几个方法中可以配置或释放资源。
      

  6.   

    to Apple:
    “申请接口”指的是创建接口么?
      

  7.   

    谢谢苹果。
    但如果接口(声明为private变量)按需创建--也就是在接口的方法中使用到该接口的时候才创建之,但使用完后不释放--在这种情况下需要在onActive事件中释放这些接口么?
    还有:你说“在OnActivate中申请接口,OnDeactivate中将所申请的接口释放,为的是让所调用的接口提交或回滚所拥有的事务”,也就是说只有将相应的接口释放,事务才能真正的提交或回滚,是/否?
      

  8.   

    组件池化后,虽然客户端保存组件的接口指针,可是组件本身还是会调用Destroy。
    在OnActive中进行ADOConnection.Connectioned := true后,即使不在OnDeactivate中断开数据库连接,由于组件本身要调用Destroy,所以也可以由组件本身断开数据库连接。
    即使在组件中不显示的写释放拥有的接口指针,由于会自动调用Destroy,所以其实还是会释放的。还是没找到真正提交事务的地方。:(
    奇怪的是,每次调用时,都会调用Initialize方法和OnActive方法,可如果你把创建数据库链接的代码写到Initialize中,就是不行。
    是不是我没有实现对象池啊,怎么看着不像啊。
      

  9.   

    “即使在组件中不显式的写释放拥有的接口指针,由于会自动调用Destroy,所以其实还是会释放的”,哈哈,说的对啊。
      

  10.   

    让Peter兄见笑啦,其实苹果没有真正实现对象池,由于自己用的事务对象,所以还要在Initialize方法中写Pooled := true。在书上找到这样一句话:
    **********************************************************************************
    调用结束后执行Dispose,使该对象由活动状态变为非活动状态,此时该对象的Deactive被执行,紧接着该对象的CanBePooled方法被调用。如果该方法返回true,则该对象就作为非活动对象留在线程池。
    **********************************************************************************
    Delphi为我们封装了CanBePooled,用Pooled := true即可实现。还有测试结果,即使不释放拥有的接口指针,事务也会回滚,不过用到的组件对象就不能释放啦,还是写上的好。
      

  11.   

    如果不释放用到的组件对象,则在客户组件释放(放到pool中)时,这些组件对象就不能释放(也放到了pool中?or未放到pool中,但一直不能被再次使用?)。
    Apple,你说的是这个意思么?
      

  12.   

    我一直都自己实现Pool,看来要好好学习COM+
      

  13.   

    如果不释放用到的组件对象,对象确实未释放,从COM+服务器中可以看到对象一直存在
      

  14.   

    呵呵,如果你设置了闲置关闭时间,倒是可以在到指定时间的时候由COM+服务器来关闭对象:)
      

  15.   

    eastliangliang TOMWLD
    你们两个问题解决了也不跟我说一声啊?
      

  16.   

    看来苹果是孤独高手啊,等我研究COM+ Events, MSMQ等问题是一定寻你请教。
    Object Pooling我还没有真正用于程序中,不过正准备使用,等发现问题再请赐教。