Firedacでは、スレッド接続をサポートする簡単な方法はありません。デフォルトでは、FireDac接続はスレッドセーフではありません。これは、複数のスレッドを使用してデータベースで同じ接続を使用して物事を実行しようとする場合、これは例外をもたらす可能性があります(そして通常はそうするでしょう)。このライブラリには、これを簡単にする接続プールを介してこれに対するソリューションが含まれています。
接続プールは、接続定義で作業していることを前提としています。これは、デフォルトで使用されない場合でも、動的にも簡単に実装できます。例は、アプリケーションの主要な形式で見つけることができます。接続プールを使用して接続を要求できます。プールは、スレッドと指定された接続定義に接続が既に存在するかどうかを確認します。その場合、接続が返されます。そうでない場合は、作成および登録されます。アプリケーションの実行中にこの管理を正しく保つために、シングルトンの実装が追加されました。
接続プールでデフォルト接続定義の名前を登録できるため、毎回指定する必要はありません。接続を要求するスレッドのIDは、プールによって自動的に決定することもできます。
接続プールを使用したいスレッド用のベースクラスもあります。このベースクラスを使用した例も含まれており、アプリケーションの主要な形式で解決しました。
プロジェクトまたはデータモジュールにThreadedConnections.Singletonを含めます。 SetConnectionPoolDefaultsメソッドを呼び出して、接続プールのSingletonを初期化します。例えば:
SetConnectionPoolDefaults('SQLite', 'MainDatabase');
この例では、 'SQLite'はドライバーであり、 'MainDatabase'接続定義の名前です。
接続定義が使用されていない場合は、接続と同じパラメーターを使用して動的に簡単に作成できます。次の例は、 dmDatabase.DbConnectionという接続があることを前提としています。
const DefinitionName = 'MainDatabase';
var Definition := FDManager.ConnectionDefs.FindConnectionDef(DefinitionName);
if not Assigned(Definition) then
begin
var Connection := dmDatabase.DbConnection;
FDManager.AddConnectionDef(DefinitionName, Connection.ActualDriverID, Connection.Params);
end;
Singletonを使用する場合、 GetConnectionPool関数を使用してそのインスタンスを取得できます。この関数は、 ThreadedConnections.Singletonユニットで使用できます。プールには、接続を要求するために多くのGetConnection関数にアクセスできます。 NOパラメーターバリアントは、デフォルトの接続定義と現在のスレッドに対してこれを行っていると想定しています。これはメインスレッドにもなります。
var Pool := GetConnectionPool;
var DefaultConnection := Pool.GetConnection;
var SpecificConnection := Pool.GetConnection('FinancialDatabase', Self.ThreadID);
TThreadedConnectionThreadスレッドのスーパークラスとして使用できます。このクラスは、作成に関する接続プールのインスタンスを期待しています。サブクラスで簡単に接続を取得するための標準関数を提供します。この例は、 ThreadedConnections.Example.Threadsにあります。もちろん、スレッドのスーパークラスでの実装の例として、スーパークラスを使用することも可能です。
TThreadedConnectionThread SuperClassとして使用する場合の使用方法の例は次のとおりです。
TMyDatabaseThread = class(TThreadedConnectionThread)
protected
procedure Execute; override;
end;
TMyDatabaseThread.Execute;
begin
var Query := TFDQuery.Create;
try
Query.Connection := GetConnection;
...
finally
Query.Free;
end;
end;
var Thread := TMyDatabaseThread.Create(True, GetConnectionPool);
Thread.Start;