【发布时间】:2014-07-14 17:50:47
【问题描述】:
我们注意到,当 DevForce 请求超时时,会自动重试。论坛here 也提到了这种行为。在该论坛帖子中,建议的解决方案是增加超时以尝试完全避免该问题。对我们来说,这并不是一个真正可行的解决方案。我们知道有些操作会超时,增加超时不是一个可接受的解决方案。
更糟糕的是,如果调用是存储过程查询或 InvokeServerMethod 调用,则该调用很可能不是 idempotent,因此再次重试并不安全,而且很可能最终弊大于利。我们已经开始在我们的应用程序中遇到类似的情况,这造成了很大的痛苦。一个简单的例子是:我们调用一个创建项目副本的存储过程。如果复制时间太长,它将不断重试,但这仅意味着我们有 3 个复制操作并行进行。最终结果是最终用户收到错误(因为第 3 次重试仍然超时)但(最终)将有该项目的三个副本(存储过程最终将完成 - 重试逻辑似乎不会取消以前的请求-我什至不确定是否可以取消)。这是比较良性的例子之一 - 在其他情况下,重试操作可能会导致更严重的问题。
我从6.1.6 release notes 看到,DevForce 不再为保存执行自动重试。我真的很想看到这种行为扩展到 StoredProcedureQueries 和 InvokeServerMethods。对于正常的 EntityQuery 操作(甚至可能是 Connect/Disconnect 调用),我对 rety 很好。如果这不是 DevForce 核心中可以改变的东西,有没有办法让它可配置或提供一些自定义方式让我们注入控制它的代码?
【问题讨论】:
-
我们谈论的是 DevForce 2010 还是 2012?在 DF2010 中,InvokeServerMethod 与 SaveChanges 一样,不应进行重试。在 DF2012 中,有一个突出的功能请求以某种方式使自动重试可配置,我们可能应该提高优先级并实现这一点。 DF2010 的功能请求也是一种选择,但优先级较低。
-
我也应该在 DF2012 中添加,如果您正在进行异步调用,您可以使用 CancellationToken 来解决重试问题。
-
我参加的是 DevForce 2012。至于 CancellationToken,这有什么帮助?我不是重试的人,所以我不确定我会取消什么。这种取消不会停止存储过程或其他服务器端操作,对吧?更多的只是客户端放弃了请求?
-
如果您向异步 EntityManager 调用提供 CancellationToken 并将其设置为在一段时间后取消,则客户端将放弃该请求。这与 WCF 通道超时并没有什么不同,后者也会使服务器请求继续运行。这就是为什么如果这是您看到的超时类型,增加您的 WCF 超时值可能是一个好主意。
-
增加超时似乎只会导致军备竞赛。我将超时时间增加到 10 分钟。但是我在 11 分钟的请求中遇到了同样的问题。我将超时时间增加到 20 分钟,然后我在 21 分钟的请求中遇到了同样的问题,等等。在某些情况下,更高的超时时间可能会有所帮助,但这并不是我们真正想要的。并且最好避免必须更新每个异步调用以包含 CancellationToken。这对我们来说将是很多变化。能够配置重试逻辑对我来说似乎更有希望...... :-)