0

我们有一个用于比萨店的 Delphi7 + UIB + Firebird 2.5 应用程序,在有线网络上运行稳定。
但是在 wifi 上,(使用 Win8/Win10 平板电脑)如果连接断开,UIBDatabase 无法自动重新连接。

(我们目前正在对整个APP进行重构,去除“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:=Falseor关闭当前连接,.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.

所以无论我们做什么,我们都无法重新连接!

最坏的情况是 TabletPC 进入睡眠模式时,因为连接肯定断开,但组件认为它仍然在线。它至少需要 8 秒才能意识到无法执行查询。

我们之前尝试启动 TTimer 以在 2000 毫秒后强制取消操作,但该事件永远不会被触发。

所以我想知道:

  • 有没有办法妥善处理这些案件?
  • 没有其他人有这样的问题吗?(此处为每个相关主题红色,仅找到1 个相似与 0 个解决方案。)
  • 当前可从此处下载的 UIB 组件是否不稳定(由于许多 SynEdit 不兼容错误,很难在 D7 下编译!)
  • 为什么只有在我尝试重新连接后才会.OnConnectionLoss触发事件?
  • 是否可以重新连接到:
    再次相同的事务
    完成查询
    并正确提交和关闭?
    (因为我们可以从 Firebird 读取事务 ID。) ...所以服务器不需要将其保持打开 2 个多小时。
4

1 回答 1

0

错误 1:
在 ca.50 的 1 个位置意外键入 tpConsistency 而不是 tpConcurrency。
那锁定了整个表,所以不可能连接回来

错误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
没有找到任何解决方案来重新连接到之前丢失的 SAME 事务。

于 2019-09-10T19:53:22.487 回答