通过客户端 - 服务器断开连接管理SQLConnection / Datasnap

时间:2012-12-12 16:30:29

标签: delphi delphi-xe2 sqlconnection datasnap disconnect

在我的Datasnap客户端应用程序中,我使用1个TSQLConnection作为我的方法和ProviderConnection。 连接丢失时出现问题。 TSQLConnection.Connected和TSQLConnection.ConnectionState都没有捕获到它。

当我的TSQL连接打开但我丢失了互联网连接,或者服务器停止了。 Datasnap客户端应用程序提供了大量错误。 (服务器方法或ClientDatasets)

我已经创建了一个函数来管理我的服务器方法的SQL连接。但是当例如关闭通过TDSProviderConnection连接的ClientDataset时会出现更多问题。

问:如何管理客户端应用程序以安全地捕获TSQL连接上的任何断开连接。 :您如何管理停机时间,以及如何处理未保存的客户端状态。

停机后重新连接不是问题。

调用servermethod时:这会抛出异常。

tmpM:=TServerMethodsClient.Create(MYTSQLCONNECTION.dbxconnection,true);

所以我写下一个方法,用虚拟方法从我的数据模块中获取TSQLCONNECTION。

function TDMForm.DSConnection: TSQLConnection;
var
  tmpM:TServerMethodsClient;
begin
  result:=nil;
  if assigned(MYTSQLCONNECTION) then begin
    tmpM:=TServerMethodsClient.Create(MYTSQLCONNECTION.dbxconnection,true);
    try
      try
        tmpM.Ping;
        result:=MYTSQLCONNECTION
      except
        ReconnectForm.ShowModal; // has a reconnect button that tries to reconnect + shutdownbutton
        if ReconnectForm.modalresult=mrOK then
          result:=MYTSQLCONNECTION
        else
          MainForm.Close;
      end;
    finally
      tmpm.Free;
    end;
  end;
end;

我用这种方式编写了Method,因为只有找出连接是否丢失的方法是通过伪方法才会抛出同样的错误...然后我可以查询重新连接或关闭程序。

编辑:(我期待某种一般的答案和指导方针,不管是不是。不是我的代码更正,这只是为了表明我现在在做什么。)

1 个答案:

答案 0 :(得分:4)

我们遇到了同样的问题 - 如何检测连接断开的时间,以及如何优雅地重新连接。这就是我们最终做的事情,事实证明这对我们来说非常成功。

我们的用户连接到DataSnap服务器以检索数据并进行更改。所有记录创建,更新和删除都通过OnBeforePost中的OnBeforeDeleteTClientDataSet事件处理程序立即提供给数据库。

由于在尝试与服务器通信并发现连接已被切断之前,您无法检测到客户端何时被强制断开与DataSnap服务器的连接,因此我们在主表单中添加了TApplicationEvents在我们的应用程序中,为OnException事件编写了一个事件处理程序。当我们看到EIdSocketError时,我们知道连接已失效,因此我们会向用户显示一条消息,然后拨打Abort以便Post或{{1} }不会发生在本地数据集中。用户可以重新登录,然后再次点击保存删除以完成之前的操作。

我们的全局异常处理程序如下所示:

Delete

procedure TMainForm.AppEventsException(Sender: TObject; E: Exception); begin if E is EIdSocketError then begin AppEvents.CancelDispatch; MessageDlg('The connection to the database was lost. You must log in before you retry the failed action. Actual error message:'#13#10#13#10 + E.Message, mtError, [mbOK], 0); Abort; end; if E is TDBXError then begin AppEvents.CancelDispatch; MessageDlg('The database returned an error. If you cannot correct the issue, please contact customer service with the following database error message:'#13#10#13#10 + E.Message, mtError, [mbOK], 0); Abort; end; // Show any other unhandled exceptions Application.ShowException(E); end; 是我们陷阱的另一个,因为它通常意味着发生了DB错误,如外键或唯一键冲突。由于未在数据库中进行更改,因此我们TDBXError在本地进行更改,这使我们与数据库保持同步。

由于我们处理与db同步的方式(通过AbortOnBeforePost),连接被切断并且用户重新连接并获得新的DataSnap会话并不重要。我们甚至可以在没有用户丢失更改的情况下重启DataSnap服务器等。他们只需再次登录并单击保存。什么都不会丢失。

所有这些都回答了您的第一个问题......有一天,我们将实施离线模式,OnBeforeDelete可以保存到用户的硬盘,下次登录时,我们会同步申请所有本地保存的更改。但我们还没有这样做 - 所以我对你的第二个问题没有一个好的答案。