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

r_j*_*r_j 9 delphi sqlconnection datasnap disconnect delphi-xe2

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

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

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

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

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

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

tmpM:=TServerMethodsClient.Create(MYTSQLCONNECTION.dbxconnection,true);
Run Code Online (Sandbox Code Playgroud)

所以我写下一个方法,用虚方法从我的数据模块中获取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;
Run Code Online (Sandbox Code Playgroud)

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

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

Jam*_* L. 4

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

我们的用户连接到 DataSnap 服务器来检索数据并进行更改。OnBeforePost所有记录的创建、更新和删除OnBeforeDelete都会通过TClientDataSet.

由于在尝试与服务器通信并发现连接已被切断之前,您无法检测客户端何时与 DataSnap 服务器强制断开连接,因此我们在应用程序的TApplicationEvents主窗体中添加了一个事件处理程序为了这次OnException活动。当我们看到 时EIdSocketError,我们知道连接已断开,因此我们向用户显示一条消息,说明该信息,然后调用,Abort以便本地数据集中不会发生Post或。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;
Run Code Online (Sandbox Code Playgroud)

TDBXError是我们捕获的另一个错误,因为它通常意味着发生了数据库错误,例如外键或唯一键违规。由于更改不是在数据库中进行的,因此我们Abort在本地进行更改,这使我们与数据库保持同步。

由于我们处理与数据库同步的方式(通过OnBeforePostOnBeforeDelete),连接被切断并且用户重新连接并获得新的 DataSnap 会话并不重要。我们甚至可以重新启动 DataSnap 服务器,而用户不会丢失所做的更改等。他们只需再次登录并单击“保存”即可。没有什么是永远不会失去的。

所有这些都回答了您的第一个问题...有一天,我们将实现离线模式,TClientDataSet可以将其保存到用户的硬盘上,并且下次他们登录时,我们将进行同步以应用所有本地保存的更改。但我们还没有这样做——所以我对你的第二个问题没有一个好的答案。