网络丢失后如何重新连接到相同的UIBDatabase + UIBTransaction? [英] How to reconnect to the same UIBDatabase + UIBTransaction after network-loss?

查看:93
本文介绍了网络丢失后如何重新连接到相同的UIBDatabase + UIBTransaction?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们有一个适用于比萨店的Delphi7 + UIB + Firebird 2.5应用程序,可在有线网络上稳定工作.
但是在wifi上,(与Win8/Win10 TabletPC配合使用)如果连接断开,则UIBDatabase无法自动重新连接自身.

We have a Delphi7 + UIB + Firebird 2.5 application for pizzerias, working rock stable on wired networks.
But on wifi, (working with Win8/Win10 TabletPCs,) if the connection is broken, UIBDatabase can not reconnect itself automatically.

(我们目前正在重建整个APP,以删除"IBX遗留物",但是将 UIB升级为最新版本,问题似乎更加严重!)

(We are currently reconstructing the whole APP to remove "IBX leftovers", but after upgrading UIB to the latest version, problems seems to be even worse!)

在出现典型的连接丢失后,出现错误消息msg.是:

After a tipical connection loss, an error msg. is:

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 关闭当前连接,也无法再次重新连接:

Even if I try to close the current connection with .IsConnected:=False or .CancelAbort It can not reconnect again any more:

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.

因此,无论我们做什么,我们都无法重新连接!

So whatever we do, we can not reconnect!

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

The worst case is when the TabletPC goes into sleep mode, because the connection is definitely broken, but the component thinks it's still online. It takes minimum of 8 seconds for it to realize the query can not be executed.

我们尝试过启动TTimer,然后在2000ms之后强制取消操作,但该事件从未触发过.

We've tried to start a TTimer before to force cancel the operation after 2000ms, but that event never gets fired.

所以我想知道:

  • 有没有办法正确处理这些情况?
  • 没有其他人有这样的问题吗?(红色此处的所有相关主题,仅找到 1个相似的含0个解决方案.)
  • 当前的UIB组件是否可从此处下载,而不稳定?(由于许多SynEdit不兼容错误,很难在D7下进行编译!)
  • 为什么在仅在我尝试重新连接后才触发 .OnConnectionLoss 事件?
  • 是否可以重新连接到:
    再次进行相同的交易
    完成查询
    和提交和正确关闭吗?
    (因为我们可以从Firebird中读取交易ID.) ...因此服务器无需将其保持打开状态2个小时以上.
  • Is there a way to handle these cases properly?
  • Nobody else has problems like this? (Red every related topic here, found only 1 similar with 0 solution.)
  • Is the current UIB component downloadable from here not stable? (Had' hard time to compile under D7 because of many SynEdit incompatibility errors!)
  • Why is .OnConnectionLoss event fired only after I'm trying to reconnect again?
  • Is it possible to reconnect to the:
    SAME transaction again,
    finish the query
    and Commit & close properly?
    (Since we can read the transaction ID from Firebird.) ... so the server won't need to hold it open for 2+ hours.

推荐答案

错误1:
在大约50的1个地方意外键入了tpConsistency,而不是tpConcurrency.
锁定了整个桌子,所以不可能重新连接

Error 1:
Accidentally typed tpConsistency instead of tpConcurrency at 1 place of ca.50.
That LOCK-ed the whole table, so it was impossible to connect back

错误2:
建议设置 myTransaction.DefaultAction:= etmRollback;

错误3:

  • 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事务的任何解决方案.

Feature request 4
Did not find any solution to reconnect to the SAME transaction previously lost.

这篇关于网络丢失后如何重新连接到相同的UIBDatabase + UIBTransaction?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆