Não há maneira fácil no FireDac para suportar conexões roscadas. Por padrão, a conexão FIREDAC não é segura por threads. Isso significa que, se você tentar fazer as coisas no banco de dados com vários threads ao mesmo tempo, usando a mesma conexão, isso pode (e geralmente resultará em exceções. Esta biblioteca contém uma solução para isso através de um pool de conexão que facilita isso.
O pool de conexões pressupõe que você esteja trabalhando com definições de conexão. Isso é fácil de implementar, mesmo dinamicamente se não for usado por padrão. Um exemplo pode ser encontrado na forma principal do aplicativo. O pool de conexão pode ser usado para solicitar uma conexão. O pool verifica para ver se já existe uma conexão para o thread e a definição de conexão fornecida. Nesse caso, a conexão é retornada, se não, é criada e registrada. Para manter essa administração correta durante a execução do aplicativo, foi adicionada uma implementação de um singleton.
Você pode registrar um nome para a definição de conexão padrão no pool de conexões, para não precisar especificá -lo a cada vez. O ID do encadeamento que solicita uma conexão também pode ser determinado automaticamente pelo pool.
Há também uma classe base para threads que desejam usar o pool de conexões. Um exemplo usando esta classe base também está incluído e elaborado na forma principal do aplicativo.
Inclua ThreadedConnections.Singleton em seu projeto ou módulo de dados. Ligue para o método SetConnectionPoolDefaults para inicializar o singleton para o pool de conexões. Por exemplo:
SetConnectionPoolDefaults('SQLite', 'MainDatabase');
Neste exemplo, 'SQLite' é o driver e 'MainDatabase' o nome da sua definição de conexão.
Se as definições de conexão não estiverem sendo usadas, você poderá criá -las facilmente usando os mesmos parâmetros que sua conexão. O exemplo a seguir assume que existe uma conexão chamada 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;
Ao usar o singleton, sua instância pode ser recuperada usando a função GetConnectionPool . Esta função está disponível na unidade ThreadedConnections.Singleton . O pool tem acesso a várias funções GetConnection para solicitar uma conexão. A variante de não parâmetro assume que você está fazendo isso para a definição de conexão padrão e para o thread atual. Este também pode ser o tópico principal.
var Pool := GetConnectionPool;
var DefaultConnection := Pool.GetConnection;
var SpecificConnection := Pool.GetConnection('FinancialDatabase', Self.ThreadID);
Você pode usar TThreadedConnectionThread como uma superclasse para seus threads. Esta classe espera uma instância do pool de conexões na criação. Ele fornece funções padrão para obter uma conexão facilmente nas subclasses. Um exemplo disso pode ser encontrado no ThreadedConnections.Example.Threads . Obviamente, também é possível usar a superclasse como exemplo para implementação em sua própria superclasse para threads.
Aqui está um exemplo de como usá -lo ao usar o TThreadedConnectionThread como 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;