I am developing a service to work with multithread of an old source code that uses BDE and DBX, so that each thread has its own connection I have developed a singleton with connection pool to which it uses the GetCurrentThreadID < strong> to find in the pool if the connection already exists and if it does not exist I create
if not Assigned(m_PoolConexoes)
then m_PoolConexoes := TObjectList.Create(True);
for i := 0 to Pred(m_PoolConexoes.Count) do
begin
if TSingletonConexao(m_PoolConexoes[i]).FThreadID = GetCurrentThreadId then
begin
Result := TSingletonConexao(m_PoolConexoes[i]);
Break;
end;
end;
if not Assigned(Result) then
begin
Result := TSingletonConexao.Create();
m_PoolConexoes.Add( Result );
TMisc.LogEventViewer(9999,'Quantidade de Conexoes Ativas: '+ IntToStr(m_PoolConexoes.Count), 9999);
end;
At the end of the thread in OnTerminate I clear the connection by the method below:
class procedure TSingletonConexao.FreeInstancia;
var
i: Integer;
begin
TMisc.LogEventViewer(9996,'Iniciando o FreeInstancia de conexão da thread : '+ IntToStr(GetCurrentThreadId), 9996);
if Assigned(m_PoolConexoes) then
begin
for i := 0 to Pred(m_PoolConexoes.Count) do
begin
if TSingletonConexao(m_PoolConexoes[i]).FThreadID = GetCurrentThreadId then
begin
m_PoolConexoes.Remove( m_PoolConexoes[i] ); // Ao remover da lista, o obj é destruído...
Break;
end;
end;
end;
TMisc.LogEventViewer(9996,'Quantidade de Conexoes Ativas: '+ IntToStr(m_PoolConexoes.Count), 9996);
end;
Destroy:
destructor TSingletonConexao.Destroy;
begin
SafeFree( FQuery );
if SafeAssigned( FConexaoDBX )
then FConexaoDBX.Close;
SafeFree( FConexaoDBX );
if SafeAssigned( FConexaoBDE )
then FConexaoBDE.Close;
SafeFree( FConexaoBDE );
TMisc.LogEventViewer(9996,'Encerrando uma Conexão com o ThreadID: '+ IntToStr(FThreadID), 9996);
inherited Destroy;
end;
The problem is that since I'm in a loop, for some reason unknown to me, the connection is not being destroyed and the Duplicate database name 'XXX' error occurs. Could someone give me a light on how to solve this? It seems that the connection is holding up even though it has been destroyed (strange).
Obs : To create the connections, I do the following, when logging on the system already exists an open connection, then I create the object and pass the attributes of the open connection by changing only the Name and DatabaseName , putting the original connection name concatenated with GetCurrentThreadID
FThreadID := GetCurrentThreadId();
with dmConexaoDireta.dbAplicacao do
begin
FConexaoBDE := TDatabase.Create(nil);
FConexaoBDE.DatabaseName := DatabaseName +'_'+ IntToStr(FThreadID);
FConexaoBDE.DriverName := DriverName;
FConexaoBDE.AliasName := AliasName;
FConexaoBDE.Exclusive := Exclusive;
FConexaoBDE.HandleShared := HandleShared;
FConexaoBDE.KeepConnection := KeepConnection;
FConexaoBDE.LoginPrompt := LoginPrompt;
FConexaoBDE.Name := FConexaoBDE.DatabaseName;
FConexaoBDE.Params.Text := Params.Text;
FConexaoBDE.ReadOnly := ReadOnly;
FConexaoBDE.SessionName := SessionName;
FConexaoBDE.TransIsolation := TransIsolation;
FConexaoBDE.Connected := True;
end;
I have tried to create TDatabase with owner Application and now I have nil .
Obs3 : The SafeAssigned and SafeFree methods are methods I use to not burst error.