MultiThreading with connection pool "Duplicate database name 'XXX'"

0

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.

    
asked by anonymous 30.11.2018 / 14:07

1 answer

0

I solved this problem by causing my thread to not end every cycle, instead I put the queue in singleton and made the thread have the intelligence to look for the next record in the queue and, if it does not find, wait 3 seconds to search again.

    
20.12.2018 / 19:06