c# - 在执行长时间运行的数据库任务时处理 Web 服务超时

标签 c# sql-server web-services architecture timeout

我们其中一款产品的架构是典型的 3 层解决方案:

  • C# 客户端
  • WCF 网络服务
  • SQL Server 数据库

客户端从网络服务请求信息。 Web 服务访问数据库以获取信息并将其返回给客户端。

问题来了。其中一些查询可能需要很长时间,而且我们事先不知道哪些查询会很慢。我们知道有些请求通常比其他请求慢,但如果有足够的数据,即使是最简单的请求也可能很慢。有时使用查询或运行大量数据的报告。在大量数据减慢查询速度之前,查询只能优化到目前为止。

如果数据库中的查询达到 SQL Server 中的最大查询超时,数据库查询将终止,Web 服务将错误返回给客户端。这是明白的。我们可以处理这些错误。

客户端正在等待网络服务调用完成。如果数据库调用耗时较长,客户端可能会在调用 Web 服务时超时。客户端放弃,但数据库请求继续处理。此时,客户端与数据库不同步。数据库调用可能成功也可能不成功。可能有错误。客户永远不会知道。在某些情况下,我们不希望我们的用户发起另一个请求,这可能会导致在上一个请求已完成的情况下出现无效状态。

我很好奇其他人是如何处理这个问题的。 您使用了哪些策略来防止 Web 服务超时影响数据库调用?

我能想到的最好的想法是在某处创建一个实际的数据库层——在网络服务内部,附加到消息队列——某处。将每个查询卸载到另一个进程似乎过多。 (话又说回来,我们并不总是知道给定的请求是快还是慢。)

如果我们能够将发出 HTTP 请求的行为与启动和运行数据库进程的行为分开,那就太好了。我在以前的公司看到过使用自定义服务器完成此操作,但它使用的是直接套接字通信,我宁愿避免用某些自定义应用程序替换 Web 服务。

请注意,考虑到我们处理的数据量,我们已经完成了查询优化。查询优化、索引等只能在数据量很大时带你走这么远。有时事情只是需要很长时间。

最佳答案

我以前遇到过类似的问题,用下面3种方法之一解决:

  1. 将所有长时间运行的查询添加到队列中,并按顺序处理这些查询。
    在我的例子中,这些都是复杂的报告,然后通过电子邮件发送给客户,或者存储在永久的“临时”表中,供客户在收到通知后查看。
  2. 我们使用 JQuery 调用调用了一个网络服务,然后在完成时调用了一个 javascript 回发方法。
    当我们不想让页面加载与 Web 服务正在执行的操作同步时,这种方法很有效。
    但是,这确实意味着在长时间运行的过程完成之前,该功能不可用。
  3. 最复杂的一个。
    我们弹出了另一个显示进度条的窗口,它还定期轮询服务器。
    这使用 session 变量来确定显示进度条的距离。
    启动进度条后,启动一个新线程,定期更新同一个 session 变量。
    一旦 session 变量值设置为 100,弹出窗口将自行关闭。
    客户喜欢这种方法。

无论如何,我希望其中之一对您有所帮助。

关于c# - 在执行长时间运行的数据库任务时处理 Web 服务超时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/522626/

相关文章:

c# - 如何访问 Windows Phone 7 中的联系人列表?

c# - 带参数的命令

c# - HttpHeaders.TryAddWithoutValidation 是否验证?

sql-server - 用索引更新表太慢

SQL 重命名列字段

每次计时器刷新后,C# 列表框选择的索引重置为 0

sql-server - 如何在 SQL studio 中以文本形式插入/编辑 Hierarchyid 字段

JavaEE + eclipseLink + TomEE 给出 java.sql.SQLSyntaxErrorException : user lacks privilege or object not found

c# - 'customObject' 类型的对象无法转换为 'customObject' 类型

c# - 从 Javascript 调用 Web 服务(传递参数和返回数据集)