我目前正在研究多線程服務器應用程序,並計劃使用Firedac進行數據訪問。從這裏提供的文檔:http://docwiki.embarcadero.com/RADStudio/Tokyo/en/Multithreading_(FireDAC),似乎不應該同時從多個線程訪問相同的TFDConnection
和/或TFDQuery
(而應根據每個線程創建這些對象)。在多線程應用程序中使用Firedac
因此,上一個鏈接中顯示的示例將TFDConnection
和TFDQuery
集中在一個TThread
對象中。但是,在我的情況下,我無法控制線程創建(由服務器環境管理)。因此,我限制我的TFDConnection
和TFDQuery
對象的生命週期過程的生命週期,它可以從多個線程可能叫做:
procedure TAPMFiredacTemplate.executeSQL(sql:string);
var
oConn: TFDConnection;
oQuery: TFDQuery;
begin
oConn := TFDConnection.Create(nil);
oQuery := TFDQuery.Create(nil);
try
oConn.ConnectionDefName := self.ConnectionDefinitionName;
oConn.Connected := True;
oQuery.Connection := oConn;
oQuery.Open(sql);
while not oQuery.Eof do
begin
// process query
oQuery.Next;
end;
finally
if assigned(oQuery) then
begin
oQuery.Close;
oQuery.Free;
end;
if assigned (oConn) then
begin
oConn.Connected := False;
oConn.Free;
end;
end;
是這種方法有效嗎?有系統地創建TFDQuery
對象是否有性能問題?
注意:爲了提高性能,我打算使用專用池連接定義(由TFDConnection
使用)。所以,即使當我釋放TFDConnection
我的理解,物理連接不被破壞,但返回到池中,而不是:
oParams := TStringList.Create;
oParams.Add('Database=localhost:c:\apm\databases\mydb.FDB');
oParams.Add('User_Name=xxxxx');
oParams.Add('Password=xxxxxx');
oParams.Add('Pooled=True');
FDManager.AddConnectionDef('Firebird_Pooled','FB',oParams);
FDManager.Active := True;
沒有爲第一種方法的性能損失。繼續閱讀[連接池](http://docwiki.embarcadero.com/RADStudio/Tokyo/en/Multithreading_(FireDAC)#Connection_Pooling)。然後你可以檢查[示例](http://docwiki.embarcadero.com/CodeExamples/Tokyo/en/FireDAC.Pooling_Sample)。 – Victoria
我正在考慮通過'FDManager'事先創建一個連接池,然後在我的過程中使用這些池連接(請參閱附加註釋)。所以即使我創建/釋放'TFDConnection',物理連接或來自池。這應該會提高性能。但是我不確定我可以做什麼來優化'TFDQuery' – BigONotation
準備查詢可能是另一個昂貴的操作。如果您的服務器支持保持連接類型,請創建查詢對象,並在客戶端連接時準備查詢,並在斷開連接時將其銷燬。然後,您可以使用準備好的查詢對象(由上下文類引用)處理每個請求。 – Victoria