Il n'y a pas de moyen facile dans FIREDAC de prendre en charge les connexions filetées. Par défaut, la connexion FIREEDAC n'est pas une file d'attente. Cela signifie que si vous essayez de faire des choses dans la base de données avec plusieurs threads en même temps, en utilisant la même connexion, cela peut (et généralement) entraîner des exceptions. Cette bibliothèque contient une solution à cela via un pool de connexion qui facilite cela.
Le pool de connexion suppose que vous travaillez avec les définitions de connexion. Ceci est facile à implémenter, même dynamiquement s'il n'est pas utilisé par défaut. Un exemple peut être trouvé dans la forme principale de l'application. Le pool de connexion peut être utilisé pour demander une connexion. Le pool vérifie si une connexion existe déjà pour le thread et la définition de connexion donnée. Si c'est le cas, la connexion est retournée, sinon, elle est créée et enregistrée. Pour garder cette administration correcte lors de l'exécution de l'application, une implémentation d'un singleton a été ajoutée.
Vous pouvez enregistrer un nom pour la définition de connexion par défaut dans le pool de connexion, vous n'avez donc pas à le spécifier à chaque fois. L'ID du thread demandant une connexion peut également être automatiquement déterminé par le pool.
Il existe également une classe de base pour les threads qui souhaitent utiliser le pool de connexion. Un exemple utilisant cette classe de base est également inclus et élaboré sous la forme principale de l'application.
Incluez ThreadedConnections.Singleton dans votre projet ou module de données. Appelez la méthode SetConnectionPoolDefaults pour initialiser le singleton pour le pool de connexion. Par exemple:
SetConnectionPoolDefaults('SQLite', 'MainDatabase');
Dans cet exemple, 'SQLite' est le pilote et 'MainDatabase' le nom de votre définition de connexion.
Si les définitions de connexion ne sont pas utilisées, vous pouvez facilement les créer dynamiquement en utilisant les mêmes paramètres que votre connexion. L'exemple suivant suppose qu'il existe une connexion appelée 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;
Lorsque vous utilisez le singleton, son instance peut être récupérée à l'aide de la fonction GetConnectionPool . Cette fonction est disponible dans l'unité ThreadedConnections.Singleton . Le pool a accès à un certain nombre de fonctions GetConnection pour demander une connexion. La variante de paramètre No suppose que vous le faites pour la définition de connexion par défaut et pour le thread actuel. Cela peut également être le fil principal.
var Pool := GetConnectionPool;
var DefaultConnection := Pool.GetConnection;
var SpecificConnection := Pool.GetConnection('FinancialDatabase', Self.ThreadID);
Vous pouvez utiliser TThreadedConnectionThread comme superclasse pour vos fils. Cette classe s'attend à une instance du pool de connexion sur la création. Il fournit des fonctions standard pour obtenir facilement une connexion dans les sous-classes. Un exemple de cela peut être trouvé dans ThreadedConnections.Example.Threads . Bien sûr, il est également possible d'utiliser la superclasse comme exemple d'implémentation dans votre propre superclasse pour les threads.
Voici un exemple de la façon de l'utiliser lors de l'utilisation du TThreadedConnectionThread comme 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;