首页 文章

BreezeJs:SaveChanges()服务器响应被删除

提问于
浏览
0

我在移动设备(cordova)上的角度应用程序中运行breezeJs,它与.Net WebApi对话 .

一切都很好,除了偶尔设备将违反PrimaryKey(来自我的SQL Server) .

我认为我将其缩小到仅在设备上数据连接不稳定时发生 . 我可以解决这些主要密钥违规的唯一方法就是服务器正在保存更改,但移动连接在响应可以从服务器返回之前就会丢失,所有内容都保存好了 .

在调用SaveChanges后,BreezeJS没有收到服务器的回复,应该会发生什么?熟悉BreezeJS的人都知道处理这种情况的方法吗?

1 回答

  • 1

    我必须在我的项目中处理相同的场景 . 我采取的方法是两部分:

    • 为失败的ajax请求添加自动重试 . 我正在使用jQuery和jQuery,所以我用google搜索“jQuery retry ajax” . 有许多不同的实现,我的有点自定义,所有都围绕着劫持onerror回调以及延迟的失败处理程序来注入重试逻辑 . 我确信Angular会有类似的方法来重试丢弃的请求 .

    • 在saveChanges失败处理程序中,添加如下逻辑:

    ...

    function isConcurrencyException(reason: any) {
        return reason && reason.message && /Store update, insert, or delete statement affected an unexpected number of rows/.test(reason.message);
    }
    
    function isConnectionFailure(reason: any): boolean {
        return reason && reason.hasOwnProperty('status') && reason.status === 0
    }
    
    entityManager.saveChanges()
       .then(... yay ...)
       .fail(function(reason) {
           if (isConnectionFailure(reason)) {
               // retry attempts failed to reach server.
               // notify user and save to local storage....
               return;
           }
    
           if (isConcurrencyException(reason)) {
               // EF is not letting me save the entities again because my previous save (or another user's save) moved the concurrency stamps on the record.  There's also the possibility that a record I'm try to save was deleted by another user.
    
               // recover... in my case I kept it simple and simply attempt to reload the entity.  If nothing is returned I know the entity was deleted.  Otherwise I now have the latest version.  In either case a message is shown to the user.  
               return; 
           }
    
           if (reason.entityErrors) {
               // We have an "entityErrors" property... this means the saved failed due to server-side validation errors.
               // do whatever you do to handle validation errors...
               return;           
           }
    
           // an unexpected exception.  let it bubble up.
           throw reason;    
       })
       .done();  // terminate the promise chain (may not be an equivalent in Angular, not sure).
    

    测试不稳定连接的方法之一是使用Fiddler's AutoResponder选项卡 . 使用与您的breeze路由匹配的正则表达式设置 *.drop 规则,并在要模拟已删除的请求时检查"Enable Automatic Responses"框 .

    Fiddler AutoResponder


    这是一个有点混乱的问题需要解决 - 没有一个尺寸适合所有答案,希望这有帮助 .


    NOTE

    沃德在下面的评论中提出了一个很好的观点 . 这种方法不适用于在服务器上生成实体主键的情况(如果您的数据库使用PK的标识列,则会出现这种情况),因为重试逻辑可能导致重复插入 .

相关问题