Firedac多个连接池

时间:2016-04-09 12:52:43

标签: delphi connection-pooling firedac mormot

我正在将客户端 - 服务器ERP应用升级到多层。我们希望为客户提供将数据库放在云中的可能性(托管在我们的服务器中)。所以,客户端是用Delphi编写的,服务器是用IOphi编写的http IOCP服务器(来自mORMot框架),对于dbs我们使用Firebird嵌入式

我们的客户(比如200)可以拥有25-30个Firebird数据库(总计5000-6000个数据库),每个客户可以访问4-5个用户。这不会一下子发生。一个用户可以在一个数据库中工作,另外两个用户可以在另一个数据库中工作,但所有数据库都应该可用并在线。所以,我可以让800-1000名用户以700-900 dbs的速度工作。数据库并不大,通常每个20-30 MB,但可以达到200 MB。

这不是数据分片,所以请不要建议将所有数据库合并在一起,我真的需要它们单独备份/恢复/替换它们。

所以,我需要多个连接池 - 对于每个数据库,我需要一个让我们说2个连接的池。我读到了有关Firedac连接池的信息。似乎TFDManager对我来说应该是完美的。我使用" Pooled = true"定义多个" ConnectionDef" s。它可以维护多个连接池(每个连接持续到几分钟不活动)。

问题:

  1. 我必须在服务器开始提供请求之前创建所有" ConnectionDef"

  2. TFDManager"可以处理"请求(以及关于不活动的超时连接),而在其他线程中我需要创建一个新数据库,因此我需要自动创建一个新的连接池并开始从新创建的数据库提供请求。在其他游泳池正在使用的时候,我实际上可以调用FDManager.AddConnectionDef(..)吗?

2 个答案:

答案 0 :(得分:2)

AFAIK Firebird嵌入式没有任何“连接”。正如其名称所述,它嵌入在同一进程中,因此不需要连接池。当多个客户端通过网络连接/断开同一个数据库时,需要连接池,而这里所有都是嵌入式的,您可以直接访问Firebird引擎。

因此,您可以:

  • 为每个Firebird嵌入式数据库定义一个“连接”;
  • 通过每个数据库的互斥锁(也称为关键部分)保护您的SOA代码。事实上,mORMot的HTTP IOCP服务器将运行来自线程池的传入请求,因此请确保安全地进行所有数据库访问。
  • 确保至少使用Firebird 2.5,因为嵌入式版本仅在修订版2.5之后被告知是线程安全的(参见the release notes)。
  • 考虑使用ZDBC / Zeos(最新的7.2 / 7.3分支),而不是FireDAC,它具有很好的功能,以及native mORMot SynDB libraries

答案 1 :(得分:0)

查看 Firedac 来源,似乎关于添加连接定义并在池模式下获取连接的所有内容都是线程安全的

添加连接定义或匹配连接定义由 TMultiReadExclusiveWriteSynchronizer 保护,并且从池中获取连接由 TCriticalSection 保护。

所以,答案:

  1. 在服务器开始提供请求之前,我不必创建所有" ConnectionDef"
  2. 是的,我可以安全地拨打FDManager.AddConnectionDef(..),而其他游泳池正在使用中。
  3. 使用Firedac,获取任何这些数据库的连接将由一个 TCriticalSection 保护。 @Arnaud Bouchez提出的解决方案通过为每个数据库创建一个 TCriticalSection 来提供更细粒度的访问,我认为会更好地扩展,但是当使用多个 TCriticalSection ,特别是所有这些都将立即启动:

    https://www.delphitools.info/2011/11/30/fixing-tcriticalsection/

    在那篇文章中提供了一个非常简单的修复此bug的方法。