2016-04-09 124 views
0

我正在將我們的客戶端 - 服務器ERP應用程序升級到多層。我們希望爲我們的客戶提供在雲中託管他們數據庫的可能性(託管在我們的服務器中)。因此,客戶端是用Delphi編寫的,服務器是一個也在Delphi中編寫的http IOCP服務器(來自mORMot框架),對於我們使用嵌入Firebird 。Firedac多個連接池

我們的客戶(比方說200)可以擁有25-30個Firebird數據庫(共5000-6000個數據庫),每個用戶可以有4-5個用戶訪問。這不是一次全部發生。一個用戶可以在一個數據庫中工作,另外兩個用戶可以在另一個數據庫中工作,但所有數據庫都應該可用並聯機。所以,我可以有800-1000用戶在700-900 DBS的工作。數據庫並不大,一般爲20-30 MB,但可以達到200 MB。

這不是數據分片,所以請不要建議將所有數據庫合併在一起,我真的需要它們單獨備份/恢復/替換它們中的每一個。

所以,我需要多個連接池 - 對於每個數據庫,我需要一個連接池。我讀了關於Firedac連接池。 TFDManager似乎對我來說應該是完美的。我使用「Pooled = true」定義了多個「ConnectionDef」,它可以維護多個連接池(每個連接持續到不活動幾分鐘)。

問題:

  1. 我有服務器開始服務請求之前創建的所有 「ConnectionDef」 S?

  2. TFDManager可以「處理」請求(並在不活動時超時連接),而在其他線程中,我需要創建一個新的數據庫,所以我需要創建一個新的連接池並開始從新服務請求創建數據庫。實際上,我可以在其他池正在使用時調用FDManager.AddConnectionDef(..)嗎?

回答

2

AFAIK Firebird embedded沒有任何「連接」。正如其名稱所述,它嵌入在相同的進程中,因此不需要連接池。當多個客戶端通過網絡連接/斷開連接到相同的數據庫時,需要連接池,而這裏全部都是嵌入式的,並且您可以直接訪問Firebird引擎。

這樣,則可以:

  • 定義每火鳥嵌入式數據庫一個 「connnection」;
  • 通過每個數據庫的互斥鎖(又稱關鍵部分)來保護您的SOA代碼。實際上,mORMot的HTTP IOCP服務器會運行來自線程池的傳入請求,因此確保所有數據庫訪問都是安全的。
  • 確保您至少使用Firebird 2.5,因爲從版本2.5開始嵌入版本被告知是線程安全的(請參閱the release notes)。
  • 代替FireDAC,考慮使用ZDBC/Zeos(最新7.2/7.3分支),它具有很好的功能,與native mORMot SynDB libraries一起使用。
+0

同意不同意 - 連接池用於在通常創建/建立新資源時需要時間和/或資源時方便獲取資源。即使將本地數據庫文件附加到fbembed.dll等進程中,也需要一些時間和資源 - 將檢查SQL權限,每個附件都會分配單獨的緩衝區,即使它是相同的進程和相同的數據庫文件(> = FB 2.5)。所以,連接池在這裏適用。 – emk

+0

定義「連接」並用關鍵部分保護它們不是連接池?那麼,爲什麼在有可用的測試車輪時發明車輪。即使您的方案看起來很簡單,因爲它只是每個數據庫的一個「連接」,我認爲我至少需要其中的兩個,因爲有時一個客戶端可以獲得較長時間的連接,因爲必須同步更大的更改日誌,因爲它是上次在線。無論如何,你的解決方案是好的,因爲它每個分區有一個關鍵部分,而Firedac每個數據庫都有一個關鍵部分。 – emk

0

看着Firedac來源,似乎所有關於添加連接定義和合並模式獲取連接是線程安全的

添加連接定義或匹配一個由TMultiReadExclusiveWriteSynchronizer把守並獲取從池中的連接是通過一個TCriticalSection保護。

所以,答案:

  1. 我沒有創造一切 「ConnectionDef」 S之前服務器啓動服務請求。
  2. 是的,我可以安全地調用FDManager.AddConnectionDef(..)而其他池正在使用。

使用Firedac,獲取任何這些數據庫的連接將受到一個TCriticalSection的保護。 @Arnaud Bouchez提出的解決方案通過爲每個數據庫創建一個TCriticalSection來提供更多的訪問權限,我認爲可以擴展得更好,但是您應該瞭解使用多個TCriticalSection時的錯誤,尤其是所有操作都將立即啓動:

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

在那篇文章中提出一個很簡單的解決了這個bug。

+0

由於您使用的是mORMot,因此您可以使用'TSynLocker'記錄或IAutoLocker'''TAutoLocker'接口/類修復'TCriticalSection'錯誤,允許在一次調用中保護整個方法,並使用填充空間來存儲一些值,這些值將被鎖保護。請參見[TAutoLocker](http://synopse.info/files/html/api-1.18/SynCommons.html#TAUTOLOCKER)和[TSynLocker](http://synopse.info/files/html/api-1.18/SynCommons。 html#TSYNLOCKER)文檔。 –