繁体   English   中英

IdHTTPserver:共享ADOConnection

[英]IdHTTPserver: Share ADOConnection

我正在使用TIdHTTPServer创建一个简单的Indy网络服务器。 在几乎所有请求中,服务器都需要与数据库通信(通过TAdoConnection )。 看到数据库连接在资源方面有点昂贵,我想创建一个池重用连接的池机制; 而不是在每个请求上建立连接。

我搜索的例子没有成功。 这篇关于Embarcadero论坛的链接建议对TIdSchedulerOfThreadPoolTIdThreadWithTask的后代进行子类 但我仍然无法将它们全部融合在一起。

我是否需要覆盖TIdSchedulerOfThreadPool.NewThread方法并让它返回我的子类TIdThreadWithTask对象,而该对象又拥有自己的TAdoConnection对象?

有人有例子吗? 我是否应该不担心这一点,只是在每个请求上打开数据库连接?

你为什么不亲自管理游泳池?

你有一个连接列表。 它开始是空的。 每次请求到来时,您都会查找可用的连接(活动但未使用的连接)。 如果没有找到,则创建一个并将其放入列表中,作为不可用。 请求结束后,将连接设置为可用。

在那里,做到了,不要后悔这样做! 几个值得关注的问题:

  • 始终牢记线程安全:
    • 查询列表时
    • 查询连接的可用性时
    • 设置连接的可用性时
  • 有时,检查是否有太多未使用的连接可用,可能比您需要的多,因此必须将它们设置为不可用,从列表中删除然后关闭。

您还必须确保在每个线程中正确设置COM并调用该对:CoInitialize / CoUnitialize

下面是要包含在项目中的示例单位。 在您的HTTP服务器构造函数中,只需创建自定义调度程序,Indy将使用它而不是默认值。

如果执行此操作,则将为COM正确初始化每个客户端线程,并且还可以添加将由所有客户端线程共享的其他项。

我还为每个连接创建了一个自定义TIdServerContext后代(并在HTTP Server构造函数中设置了ContextClass属性。)不同类型的服务器具有不同的TIdServerContext后代,但它们都使用TsoIndyCOMEnabledSchedulerOfThread基本线程类,因为它们都执行某些COM分类。

我不会将ADO Connection放入Thread中,而是放入Context中......特别是如果你将其进一步放入线程池中。

unit ExampleStackOverflow;

interface

uses
  SysUtils, Classes,
  ActiveX,
  IdThread, IdSchedulerOfThreadDefault;

type
  //Meant to be used with a custom TIdSchedulerOfThreadDefault descendant
  //to ensure COM support on child threads.
  TsoIndyComThreadWithTask = class(TIdThreadWithTask)
  protected
    //Ensure COM is setup before client connection/thread work
    procedure BeforeExecute; override;
    //Graceful COM cleanup on client connection/thread
    procedure AfterExecute; override;
  end;


  TsoIndyCOMEnabledSchedulerOfThread = class(TIdSchedulerOfThreadDefault)
  public
    constructor Create(AOwner:TComponent); reintroduce;
  end;



implementation

procedure TsoIndyComThreadWithTask.BeforeExecute;
begin
  CoInitialize(nil);
  inherited;
end;


procedure TsoIndyComThreadWithTask.AfterExecute;
begin
  inherited;
  CoUninitialize();
end;


constructor TsoIndyCOMEnabledSchedulerOfThread.Create(AOwner:TComponent);
begin
  inherited;
  //the whole reason for overriding default scheduler of thread is to setup COM
  //on client threads
  ThreadClass := TsoIndyComThreadWithTask;
  Name := Name + 'COMEnabledScheduler';
end;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM