IdHTTPserver:共享 ADOConnection

发布于 2024-12-04 17:23:09 字数 626 浏览 0 评论 0原文

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

我没有成功地寻找例子。 Embarcadero 讨论论坛上的此链接建议对 TIdSchedulerOfThreadPool< 的后代进行子类化/strong> 和 TIdThreadWithTask。但我仍然无法把它们整合在一起。

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

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

I am creating a simple Indy webserver using TIdHTTPServer. On almost all request the server needs to communicates with a database (via TAdoConnection). Seeing that database connections are somewhat expensive in terms of resources, I would like to create a pooling mechanism to reuse connections; rather than making the connection on each request.

I have searched unsuccessfully for examples. This Link on Embarcadero Discussion Forums suggests sub-classing descendents of TIdSchedulerOfThreadPool and TIdThreadWithTask. But I still cannot get it all together.

Will I need to override the TIdSchedulerOfThreadPool.NewThread method and have it return my sub-classed TIdThreadWithTask object which in turn would have it's own TAdoConnection object?

Does anyone have an example? Should I not even worry about this and just open the database connection on each request?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

柳若烟 2024-12-11 17:23:09

你为什么不自己管理这个池呢?

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

去过那里,做过那件事,一点也不后悔!关注的几点:

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

Why don't you manage the pool yourself?

You have a list of connections. It starts empty. Every time a request comes, you look for available connections (connections which are active but not being used). If none are found, you create one and put it in the list, as unavailable. Once the request ends, you set the connection to available.

Been there, done that, do not regret doing it at all! A few points of concern:

  • Keep thread safety in mind all times:
    • When you query the list
    • When you query a connection's availability
    • When you set a connection's availability
  • From time to time, check if you have too many unused connections available, there might be more than you need, so they must be set to unavailable, removed from the list and then closed.
蓝颜夕 2024-12-11 17:23:09

您还必须通过调用 CoInitialize/CoUnitialize 对来确保在每个线程中正确设置 COM。

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

如果这样做,那么每个客户端线程都将为 COM 正确初始化,并且您还可以添加将由所有客户端线程共享的其他项目。

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

我不会将 ADO 连接放入线程中,而是放入上下文中......特别是如果您将其进一步放入线程池中。

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;

You also have to ensure COM is setup correctly in each thread with a call to the pair: CoInitialize/CoUnitialize

Below is an example unit to include in your project. And in your HTTP server constructor simply create your custom scheduler and Indy will use this instead of the default.

If you do this, then each client thread will be properly initialized for COM and you can also add other items that will be shared by all client threads.

I also create a custom TIdServerContext descendant for each connection (and set the ContextClass property in the HTTP Server constructor as well.) Different types of servers have different TIdServerContext descendants, but they all utilize the TsoIndyCOMEnabledSchedulerOfThread base thread class as they all do COM of some sort.

I wouldn't put the ADO Connection into the Thread, but rather into the Context...especially if you carry this further into a thread pool.

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;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文