Как правльно сделать Free транзакции на "мертвом" соединении?

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

Ответить
GreyCrazyWolf
новенький
Сообщения: 13
Зарегистрирован: 02.03.2023 14:23:57

Как правльно сделать Free транзакции на "мертвом" соединении?

Сообщение GreyCrazyWolf »

Добрейшего времени суток.
Возник следующий вопрос. Написал приложение использующее самописный пул запросов к БД PostgreSQL. Все в общем работает, есть одно небольшое но: если соединение "падает", например закрыто сервером по таймауту, и в этот момент была открыта транзакция при попытке "Destroy" начинается ругань на " Operation cannot be performed on an active transaction".
Попробовал сделать так

Код: Выделить всё

/// деструктор
destructor TPgConnection.Destroy;
begin
  // "прибиваем" транзакцию
  if Assigned(fSQLTransaction) then
     begin
       try
           if fSQLTransaction.Active then
              fSQLTransaction.Rollback;
       except
         on E: Exception do
            begin
                 LogToFile('CONN_DESTRUCTOR', Format('Ignoring exception during transaction rollback on destroy: %s', [E.Message]), Warning);
            end;
       end;
       fSQLTransaction.DataBase := nil;
     end;
  // "прибиваем"  соединение
  if Assigned(fPQConnection) then
     begin
       try
           if fPQConnection.Connected then
              fPQConnection.Connected := False;
       except
           on E: Exception do
            begin
                 LogToFile('CONN_DESTRUCTOR', Format('Ignoring exception during connection on destroy: %s', [E.Message]), Warning);
            end;
       end;
     end;

   try
     LogToFile('CONN_DESTRUCTOR', Format('Destroing connection %s', [GUIDToString(Guid)]), Info);
     fSQLTransaction.Free;
     fPQConnection.Free;
     LogToFile('CONN_DESTRUCTOR', Format('Destroy connection %s', [GUIDToString(Guid)]), Info);
   except
     on E: Exception do
        begin
           LogToFile('CONN_DESTRUCTOR', Format('Exception during free component on destroy connection %s: %s', [GUIDToString(Guid), E.Message]), Warning);
        end;
   end;
   inherited Destroy;
end;                   
все равно в лог падает 'Ignoring exception during transaction rollback on destroy"
Оно как бы и нечего, но как-то неаккуратненько :roll:
Аватара пользователя
WAYFARER
энтузиаст
Сообщения: 565
Зарегистрирован: 09.10.2009 00:00:04
Откуда: г. Курган

Сообщение WAYFARER »

Проверяйте не только активна ли транзакция, но и живо ли подключение.

Код: Выделить всё

if Assigned(fSQLTransaction) then
  begin
    // Rollback имеет смысл только если соединение живое
    if Assigned(fPQConnection) and fPQConnection.Connected and fSQLTransaction.Active then
    begin
      try
        fSQLTransaction.Rollback;
      except
         ...
      end;
    end;
    fSQLTransaction.DataBase := nil;
    FreeAndNil(fSQLTransaction);
  end;
Ответить