No hay una manera fácil en Firedac para soportar conexiones roscadas. Por defecto, la conexión FirEdac no es segura. Esto significa que si intenta hacer cosas en la base de datos con múltiples hilos al mismo tiempo, usando la misma conexión, esto puede (y generalmente) dar como resultado excepciones. Esta biblioteca contiene una solución a esto a través de un grupo de conexión que lo hace más fácil.
El grupo de conexión supone que está trabajando con definiciones de conexión. Esto es fácil de implementar, incluso dinámicamente si no se usa de forma predeterminada. Se puede encontrar un ejemplo en la forma principal de la aplicación. El grupo de conexión se puede usar para solicitar una conexión. La piscina verifica si ya existe una conexión para el hilo y la definición de conexión dada. Si es así, la conexión se devuelve, si no, se crea y se registra. Para mantener esta administración correcta durante la ejecución de la aplicación, se ha agregado una implementación de un singleton.
Puede registrar un nombre para la definición de conexión predeterminada en el grupo de conexión, para que no tenga que especificarlo cada vez. La ID del hilo solicitando una conexión también puede determinar automáticamente el grupo.
También hay una clase base para hilos que desean usar el grupo de conexión. También se incluye un ejemplo que usa esta clase base y se resuelve en la forma principal de la aplicación.
Incluya ThreadedConnections.Singleton en su proyecto o módulo de datos. Llame al método SetConnectionPoolDefaults para inicializar el singleton para el grupo de conexión. Por ejemplo:
SetConnectionPoolDefaults('SQLite', 'MainDatabase');
En este ejemplo, 'SQLite' es el controlador y 'MainDatabase' el nombre de su definición de conexión.
Si las definiciones de conexión no se utilizan, puede crearlas fácilmente usando dinámicamente los mismos parámetros que su conexión. El siguiente ejemplo supone que hay una conexión llamada 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;
Al usar el singleton, su instancia se puede recuperar utilizando la función GetConnectionPool . Esta función está disponible en la unidad ThreadedConnections.Singleton . El grupo tiene acceso a una serie de funciones GetConnection para solicitar una conexión. La variante sin parámetro supone que está haciendo esto para la definición de conexión predeterminada y para el hilo actual. Este también puede ser el hilo principal.
var Pool := GetConnectionPool;
var DefaultConnection := Pool.GetConnection;
var SpecificConnection := Pool.GetConnection('FinancialDatabase', Self.ThreadID);
Puede usar TThreadedConnectionThread como una superclase para sus hilos. Esta clase espera una instancia del grupo de conexión en la creación. Proporciona funciones estándar para obtener fácilmente una conexión en las subclases. Un ejemplo de esto se puede encontrar en ThreadedConnections.Example.Threads . Por supuesto, también es posible usar la superclase como ejemplo para la implementación en su propia superclase para hilos.
Aquí hay un ejemplo de cómo usarlo cuando se usa TThreadedConnectionThread como superclase:
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;