我有Delphi(XE)DataSnap应用程序(Firebird / IBX),整个对象图保存在几个单独的TclientDataSets中:InvoiceCDS,InvoiceLineCDS,GoodCDS。当用户保存数据时,DataSnap客户端应用程序调用:
if InvoiceCDS.ChangeCount > 0 then InvoiceCDS.ApplyUpdates(0);
if GoodCDS.ChangeCount > 0 then GoodCDS.ApplyUpdates(0);
if InvoiceLineCDS.ChangeCount > 0 then InvoiceLineCDS.ApplyUpdates(0);
在DataSnap服务器应用程序的TDSServerModule上有3组(或更多)TDataSetProvider,TIBQuery,TIBUpdateSQL,因此 - 每个客户端CDS都与服务器表单上的相应DSP / Query / Update进行通信。每个TDataSetProvider都有AfterApplyUpdates代码:
SomeQry.Transaction.CommitRetaining;
每个TDataSetProvider也有OnUpdateError代码:
WriteErrorMessageInLog(E.Message)
据我了解,这样的OnUpdateError代码实际上只记录错误的更新调用并跳过错误记录并保存可以保存在数据库中的记录而不会出现数据库(Firebird)错误。
所有IBQueries都附加到同一个事务中,因此 - 客户端的每个ApplyUpdates调用都在服务器端的一个保留事务中执行。
这是我们应用程序的架构 - 旨在尽可能多地保存数据。但是,只有当客户端和服务器被低质量网络分离(丢包和时间滞后)时,我们才会遇到一些非常奇怪的错误。我们认为可能会有一些记录不是更新,而是保留旧值。但是服务器日志中没有错误消息(即没有OnUpdateError调用)。我们检查过在Firebird错误的情况下调用OnUpdateError,因此,我们没有Firebird错误。但数据仍未保存。
那么 - DataSnap如何处理丢失的数据包和类似的网络级别错误? 是否有可以处理网络级别问题的事件?据我所知http://docwiki.embarcadero.com/RADStudio/Berlin/en/Applying_Updates 网络错误没有机会干扰正常的应用程序流 - ClientDataSet的整个Delta数据包被发送到服务器(我想,如果DataSnap没有收到格式良好的Delta,那么它会默默地重复调用 - 这可以解释应用程序的缓慢性能,然后在具有Clumsy https://jagt.github.io/clumsy/的localhost上人为地引入网络数据包丢失,然后服务器将此delta应用于数据库。我猜来自Delta的一些记录不可能被发送到服务器,但Delta的一些记录在网络通信中丢失了,不是吗?所以,可能会出现关于丢失更新的奇怪错误?