Как повторно подключиться к той же UIBDatabase + UIBTransaction после потери сети?

У нас есть приложение Delphi7 + UIB + Firebird 2.5 для пиццерий, стабильно работающее в проводных сетях.
Но при использовании Wi-Fi (при работе с планшетными ПК Win8/Win10), если соединение разорвано, UIBDatabase не может повторно подключиться автоматически.

(В настоящее время мы реконструируем все приложение, чтобы удалить "остатки IBX", но после обновления UIB до последней версии проблемы стали еще хуже!)

После типичной потери соединения сообщение об ошибке. является:

Project ...exe raised exception class EUIBError with message 'connection rejected by remote interface
Connection not established
GDS Code: 335544421 - SQL Code: -923 - Error Code: 101'. Process stopped. 

Даже если я попытаюсь закрыть текущее соединение с .IsConnected:=False или .CancelAbort Он больше не может переподключиться:

Project ...exe raised exception class EUIBError with message 'invalid statement handle
Unsuccessful execution caused by system error that does not preclude successful execution of subsequent statements
GDS Code: 335544485 - SQL Code: -901 - Error Code: 165'. Process stopped. Use Step or Run to continue.

Итак, что бы мы ни делали, мы не можем повторно подключиться!

В худшем случае планшетный компьютер переходит в спящий режим, потому что соединение определенно разорвано, но компонент считает, что он все еще в сети. Требуется минимум 8 секунд, чтобы понять, что запрос не может быть выполнен.

Мы пытались запустить TTimer раньше, чтобы принудительно отменить операцию через 2000 мс, но это событие никогда не запускалось.

Поэтому мне интересно:

  • Есть ли способ правильно справиться с этими случаями?
  • Ни у кого больше нет таких проблем? (Выделите все связанные темы здесь, найдено только 1 подобное с 0 решением.)
  • Является ли текущий загружаемый компонент UIB от здесь не стабильна? (Было трудно скомпилировать под D7 из-за множества ошибок несовместимости SynEdit!)
  • Почему .OnConnectionLossсобытие запускается только после того, как я снова пытаюсь подключиться?
  • Можно ли снова подключиться к
    транзакции: SAME снова,
    завершить запрос
    и правильно зафиксировать и закрыть?
    (Поскольку мы можем прочитать идентификатор транзакции из Firebird.)... так что серверу не нужно будет держать его открытым более 2 часов.

1 ответ

Ошибка 1:
Случайно набран tpConsistency вместо tpConcurrency на 1 месте около 50.
Это заблокировало всю таблицу, поэтому было невозможно подключить обратно

Ошибка 2:
рекомендуется установитьmyTransaction.DefaultAction := etmRollback;

Ошибка 3:

Код UIB неверен на uiblib.pas.

  • FLockTimeout а также LockTimeout переменная должна быть целой!
  • ИСПРАВЛЕНО код параметрирования:
    function CreateTRParams(Options: TTransParams; const LockRead, LockWrite: string{$IFDEF FB20_UP}; LockTimeout: integer{$ENDIF}): RawByteString;
    ...
      begin
      {$IFDEF FB20_UP}
      if LockTimeout = 0 then
          Exclude(Options, tpLockTimeout)
      else begin // -1 = infinite,   1..2048M = seconds
          Exclude(Options, tpnoWait);
          Include(Options, tpWait );
          Include(Options, tpLockTimeout);
      end;
      {$ENDIF}
      if Options = [tpConcurrency,tpWait,tpWrite] then
        result := ''
      else
        begin
          Result := isc_tpb_version3;
          for tp := Low(TTransParam) to High(TTransParam) do
            if (tp in Options) then
            begin
              case tp of
                tpLockRead   : ParseStrOption(tpc[tp], AnsiString(LockRead));
                tpLockWrite   : ParseStrOption(tpc[tp], AnsiString(LockWrite));
              {$IFDEF FB20_UP}
                tpLockTimeout : 
    //old code: PAnsiChar(@LockTimeout)[0] + PAnsiChar(LockTimeout)[1]; << [1] causing AV error
                  case LockTimeout of
                    -1     : Result := Result + tpc[tp] + #4#127#255#255#255;
    //               0     : Result := Result + tpc[tp] + #1#0; // this would be invalid
                    1..255: Result := Result + tpc[tp] + #1 + AnsiChar(Byte( LockTimeout and $FF));
                  else //256..32k
                            Result := Result + tpc[tp] + #2 + AnsiChar(Byte((LockTimeout div $FF) and $FF)) + AnsiChar(Byte(LockTimeout and $FF));
                  end;
              {$ENDIF}
              else
                Result := Result + tpc[tp];
              end;
            end;
        end;
    end;

Запрос функции 4
Не удалось найти решение для повторного подключения к ТО ЖЕ транзакции, которая ранее была потеряна.

Другие вопросы по тегам