0

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

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

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

所以,我需要多个连接池 - 对于每个数据库,我需要一个池,比如说 2 个连接。我读到了 Firedac 连接池。看来 TFDManager 对我来说应该是完美的。我用“Pooled=true”定义了多个“ConnectionDef”,它可以维护多个连接池(每个连接持续到几分钟不活动)。

问题:

  1. 我必须在服务器开始服务请求之前创建所有“ConnectionDef”吗?

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

4

2 回答 2

2

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

因此,您可以:

  • 每个 Firebird 嵌入式数据库定义一个“连接”;
  • 通过每个 DB 的互斥体(也称为关键部分)保护您的 SOA 代码。事实上,mORMot 的 HTTP IOCP 服务器会运行来自线程池的传入请求,因此确保所有 DB 访问都是安全的。
  • 确保您至少使用 Firebird 2.5,因为嵌入式版本仅在 2.5 修订版后才被告知是线程安全的(请参阅发行说明)。
  • 考虑使用 ZDBC/Zeos(在最新的 7.2/7.3 分支中)而不是 FireDAC,它具有很好的特性,以及本机 mORMot SynDB 库
于 2016-04-09T16:50:01.953 回答
0

查看Firedac的资料,似乎所有关于在池模式下添加连接定义和获取连接都是线程安全的

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

所以,回答:

  1. 在服务器开始服务请求之前,我不必创建所有“ConnectionDef”。
  2. 是的,当其他池正在使用时,我可以安全地调用 FDManager.AddConnectionDef(..)。

使用 Firedac,获取任何这些数据库的连接将由一个TCriticalSection 保护。@Arnaud Bouchez 提出的解决方案通过为每个数据库创建一个TCriticalSection提供了更细粒度的访问,我认为可以更好地扩展,但您应该注意使用多个TCriticalSection时的错误,尤其是所有将立即启动的错误:

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

在那篇文章中提出了一个非常简单的修复这个错误的方法。

于 2016-04-11T21:22:06.597 回答