B BBM011 Unregistered / Unconfirmed GUEST, unregistred user! 2005-09-13 #1 TClientDataSet在Open和Refresh时,都不会使用已有连接的COM+对象,而是会新建一个COM+实例,也就是说我前面调用服务器的接口并通知它客户端标识就没用了,因为这时候访问到的COM服务器已不是以前的那个了。 我不想他新建COM+实例,请问怎样解决啊?
TClientDataSet在Open和Refresh时,都不会使用已有连接的COM+对象,而是会新建一个COM+实例,也就是说我前面调用服务器的接口并通知它客户端标识就没用了,因为这时候访问到的COM服务器已不是以前的那个了。 我不想他新建COM+实例,请问怎样解决啊?
B BBM011 Unregistered / Unconfirmed GUEST, unregistred user! 2005-09-13 #2 TClientDataSet在Open和Refresh时,都不会使用已有连接的COM+对象,而是会新建一个COM+实例,也就是说我前面调用服务器的接口并通知它客户端标识就没用了,因为这时候访问到的COM服务器已不是以前的那个了。 我不想他新建COM+实例,请问怎样解决啊?
TClientDataSet在Open和Refresh时,都不会使用已有连接的COM+对象,而是会新建一个COM+实例,也就是说我前面调用服务器的接口并通知它客户端标识就没用了,因为这时候访问到的COM服务器已不是以前的那个了。 我不想他新建COM+实例,请问怎样解决啊?
C chenybin Unregistered / Unconfirmed GUEST, unregistred user! 2005-09-13 #3 参考 http://www.delphibbs.com/delphibbs/dispq.asp?lid=1491917 标题: Midas配合COM+编程,为何客户端的ClientDataSet每次Open/Refresh都会导致所连接的COM+实例重建? -----------------------转自网络 ---------------------------- Sachow (2002-12-07 17:33:00) 你的这样想法,实际上是与COM技术的无状态服务器思想所背道而驰的。所谓无状态服务器 就是指服务器端不负责维护客户端打开的数据库连接、数据库光标及其它对话信息等,从而 增加能同时服务的客户端的数量。但这不表示我们就无法实现业务逻辑的连贯性操作,关键 是要客户端程序自己维护状态信息,即客户端程序自己记录上次所读取的数据表的光标所在 位置,下次存取的时候从该光标位置开始,相应程序代码应加在TClientData的BeforeGetRecords 事件和TDataSetProvider的BeforeGetRecords事件中。(详情请参考《Delphi 5.x分布式多 层应用系统篇》第5章第1节) 以我的想法:为了配合COM的无状态服务器原则,你不应该考虑让服务器知道某客户端是否 已经登录了,并帮它维护状态,而应该换一个思路,即:服务器端只以一个Login方法用于 验证客户端是否有权使用本系统,客户端判断调用Login方法的结果,如果验证通过,就继续 运行程序,并根据某些配置信息来决定该连接那个数据库。换句话说,服务器调是不设防的, 让客户端通过调用Login方法的结果来设防吧。[服务器端不设防,这样安全吗?呵呵,安全 方面的事宜交由DCOM/COM+的安全机制来负责,大家不是嫌DCOM麻烦吗?不麻烦怎么能够安全 呢?] 其它:如果你要动态连接到不同的数据库,在Oracle数据库中我知道可以采用数据链的方式,即 Select XXX From YYY@[TNSNAME]这种方式,使用SQL Server数据库我就不知道怎么做了。 ---------------------------- TClientDataSet方面在取得数据时使用BeforeGetRecords事件,在更新数据时使用 BeforeUpdateRecord事件,TDataSetProvider方面也有对应的事件,灵活使用这 些事件应该能够满足你的需要了,在Delhpi的帮助中输入“TRemoteEvent type” 还可以查到增量(分段、多次)读取数据的例子。在《Delhpi5.x ADO/MTS/COM+ 高级程序设计篇》的第10章中,有更详尽的例子。 至于是否自己建立一个继承自TClientDataSet的控件以适应你的业务逻辑,这要 你自己根据具体情况而定:这种业务逻辑需求是否有普遍性,是否会在多个项目 中采用,只有复用价值高的东西才值得封装为控件。而且,将它封装为控件将占 用你更多的时间来进行开发和测试,以适应不同的业务逻辑需求,你需要权衡一 下自己是否有那么多时间来完成这项工作。
参考 http://www.delphibbs.com/delphibbs/dispq.asp?lid=1491917 标题: Midas配合COM+编程,为何客户端的ClientDataSet每次Open/Refresh都会导致所连接的COM+实例重建? -----------------------转自网络 ---------------------------- Sachow (2002-12-07 17:33:00) 你的这样想法,实际上是与COM技术的无状态服务器思想所背道而驰的。所谓无状态服务器 就是指服务器端不负责维护客户端打开的数据库连接、数据库光标及其它对话信息等,从而 增加能同时服务的客户端的数量。但这不表示我们就无法实现业务逻辑的连贯性操作,关键 是要客户端程序自己维护状态信息,即客户端程序自己记录上次所读取的数据表的光标所在 位置,下次存取的时候从该光标位置开始,相应程序代码应加在TClientData的BeforeGetRecords 事件和TDataSetProvider的BeforeGetRecords事件中。(详情请参考《Delphi 5.x分布式多 层应用系统篇》第5章第1节) 以我的想法:为了配合COM的无状态服务器原则,你不应该考虑让服务器知道某客户端是否 已经登录了,并帮它维护状态,而应该换一个思路,即:服务器端只以一个Login方法用于 验证客户端是否有权使用本系统,客户端判断调用Login方法的结果,如果验证通过,就继续 运行程序,并根据某些配置信息来决定该连接那个数据库。换句话说,服务器调是不设防的, 让客户端通过调用Login方法的结果来设防吧。[服务器端不设防,这样安全吗?呵呵,安全 方面的事宜交由DCOM/COM+的安全机制来负责,大家不是嫌DCOM麻烦吗?不麻烦怎么能够安全 呢?] 其它:如果你要动态连接到不同的数据库,在Oracle数据库中我知道可以采用数据链的方式,即 Select XXX From YYY@[TNSNAME]这种方式,使用SQL Server数据库我就不知道怎么做了。 ---------------------------- TClientDataSet方面在取得数据时使用BeforeGetRecords事件,在更新数据时使用 BeforeUpdateRecord事件,TDataSetProvider方面也有对应的事件,灵活使用这 些事件应该能够满足你的需要了,在Delhpi的帮助中输入“TRemoteEvent type” 还可以查到增量(分段、多次)读取数据的例子。在《Delhpi5.x ADO/MTS/COM+ 高级程序设计篇》的第10章中,有更详尽的例子。 至于是否自己建立一个继承自TClientDataSet的控件以适应你的业务逻辑,这要 你自己根据具体情况而定:这种业务逻辑需求是否有普遍性,是否会在多个项目 中采用,只有复用价值高的东西才值得封装为控件。而且,将它封装为控件将占 用你更多的时间来进行开发和测试,以适应不同的业务逻辑需求,你需要权衡一 下自己是否有那么多时间来完成这项工作。
W weic Unregistered / Unconfirmed GUEST, unregistred user! 2005-09-13 #5 COM+实例的增加应该不是和ClientDataSet的Open有关吧。。。。 TDcomConnect的连接和断开会导致COM+实例的增加、减少的。 如果你没有在Clientdataset打开后断开Dcom连接,是不会增加Com+实例数量的。 ClientDataSet的Open,Close会导致数据库中的连接增加和减少。(如果是使用SQL Server的话,你可以在企业管理器中的“当前活动”中查看连接数量的变化)
COM+实例的增加应该不是和ClientDataSet的Open有关吧。。。。 TDcomConnect的连接和断开会导致COM+实例的增加、减少的。 如果你没有在Clientdataset打开后断开Dcom连接,是不会增加Com+实例数量的。 ClientDataSet的Open,Close会导致数据库中的连接增加和减少。(如果是使用SQL Server的话,你可以在企业管理器中的“当前活动”中查看连接数量的变化)
B BBM011 Unregistered / Unconfirmed GUEST, unregistred user! 2005-09-14 #6 to: weic 我在TDcomConnect连接后就没有断开,我调试一下就会发现问题的.
W weic Unregistered / Unconfirmed GUEST, unregistred user! 2005-09-15 #8 我新作了一个小例子试了一下。 中间层是ActiveX Libary+ Transationc Data Mudule,Require Transation 客户端是DcomConnection+ClientdataSet。 客户端先将DCOMConnection.connected:= True; 然后反复执行ClientDataset.Close+OPen;或者是Open后,反复执行REfresh,当前激活组件就是一个。 没有重复出你说的现象。
我新作了一个小例子试了一下。 中间层是ActiveX Libary+ Transationc Data Mudule,Require Transation 客户端是DcomConnection+ClientdataSet。 客户端先将DCOMConnection.connected:= True; 然后反复执行ClientDataset.Close+OPen;或者是Open后,反复执行REfresh,当前激活组件就是一个。 没有重复出你说的现象。
B BBM011 Unregistered / Unconfirmed GUEST, unregistred user! 2005-09-15 #9 你定义一个公共变量 Sqlstr:string; Sqlstr:=;//数据库连接字符串 在MtsDataModuleCreate事件里代码如下:// ADOConnection1.ConnectionString:=''; 写一个接口代码如下://连接COM+对象之前要先执行下面的代码 ADOConnection1.ConnectionString:=Sqlstr; 然后写一个接口创建TADODataSet,TDataSetProvider之类的ADODataSet.Connection:=ADOConnection1; 最后在客户端调用 这样写你就会发现有这情况出现了,就如下面所说的 http://www.delphibbs.com/delphibbs/dispq.asp?lid=1491917
你定义一个公共变量 Sqlstr:string; Sqlstr:=;//数据库连接字符串 在MtsDataModuleCreate事件里代码如下:// ADOConnection1.ConnectionString:=''; 写一个接口代码如下://连接COM+对象之前要先执行下面的代码 ADOConnection1.ConnectionString:=Sqlstr; 然后写一个接口创建TADODataSet,TDataSetProvider之类的ADODataSet.Connection:=ADOConnection1; 最后在客户端调用 这样写你就会发现有这情况出现了,就如下面所说的 http://www.delphibbs.com/delphibbs/dispq.asp?lid=1491917
W weic Unregistered / Unconfirmed GUEST, unregistred user! 2005-09-16 #10 如果你遇到的问题和上述那个帖子的内容一样,那我也没什么可说的了。 说实在的,你的用法本身就很奇怪。 先 方法1(设置数据库连接),在保持连接的情况下,调用方法2......等等。 你的问题就出现在,你的第一个函数上。 一般COM+的组件是无状态组件,如果是针对客户端提供的接口函数,其内部必然是这样编写的: procedure XXXXXXXX; begin try { 这里是你的代码。s } SetComplete; except setAbort; end; end; 如果你的接口函数中只是一句赋值,这个COM+本身没有被释放,保持了连接,就会出现你说的现象,每连一次产生一个。 但是如果你按照上面的写法,则调用完方法1之后,COM被释放了。再调用时,原来设置的SQL连接串已经不见了。不符合你的要求。 所以,最终你的问题的答案是。你的用法导致了COM+的运行状态。并不是ClientDataset有什么问题。 而且在客户端设置COM连接数据库连接串的方式不知是什么用意?必须这样?
如果你遇到的问题和上述那个帖子的内容一样,那我也没什么可说的了。 说实在的,你的用法本身就很奇怪。 先 方法1(设置数据库连接),在保持连接的情况下,调用方法2......等等。 你的问题就出现在,你的第一个函数上。 一般COM+的组件是无状态组件,如果是针对客户端提供的接口函数,其内部必然是这样编写的: procedure XXXXXXXX; begin try { 这里是你的代码。s } SetComplete; except setAbort; end; end; 如果你的接口函数中只是一句赋值,这个COM+本身没有被释放,保持了连接,就会出现你说的现象,每连一次产生一个。 但是如果你按照上面的写法,则调用完方法1之后,COM被释放了。再调用时,原来设置的SQL连接串已经不见了。不符合你的要求。 所以,最终你的问题的答案是。你的用法导致了COM+的运行状态。并不是ClientDataset有什么问题。 而且在客户端设置COM连接数据库连接串的方式不知是什么用意?必须这样?