我们其中一款产品的架构是典型的 3 层解决方案:
- C# 客户端
- WCF 网络服务
- SQL Server 数据库
客户端从网络服务请求信息。 Web 服务访问数据库以获取信息并将其返回给客户端。
问题来了。其中一些查询可能需要很长时间,而且我们事先不知道哪些查询会很慢。我们知道有些请求通常比其他请求慢,但如果有足够的数据,即使是最简单的请求也可能很慢。有时使用查询或运行大量数据的报告。在大量数据减慢查询速度之前,查询只能优化到目前为止。
如果数据库中的查询达到 SQL Server 中的最大查询超时,数据库查询将终止,Web 服务将错误返回给客户端。这是明白的。我们可以处理这些错误。
客户端正在等待网络服务调用完成。如果数据库调用耗时较长,客户端可能会在调用 Web 服务时超时。客户端放弃,但数据库请求继续处理。此时,客户端与数据库不同步。数据库调用可能成功也可能不成功。可能有错误。客户永远不会知道。在某些情况下,我们不希望我们的用户发起另一个请求,这可能会导致在上一个请求已完成的情况下出现无效状态。
我很好奇其他人是如何处理这个问题的。 您使用了哪些策略来防止 Web 服务超时影响数据库调用?
我能想到的最好的想法是在某处创建一个实际的数据库层——在网络服务内部,附加到消息队列——某处。将每个查询卸载到另一个进程似乎过多。 (话又说回来,我们并不总是知道给定的请求是快还是慢。)
如果我们能够将发出 HTTP 请求的行为与启动和运行数据库进程的行为分开,那就太好了。我在以前的公司看到过使用自定义服务器完成此操作,但它使用的是直接套接字通信,我宁愿避免用某些自定义应用程序替换 Web 服务。
请注意,考虑到我们处理的数据量,我们已经完成了查询优化。查询优化、索引等只能在数据量很大时带你走这么远。有时事情只是需要很长时间。
最佳答案
我以前遇到过类似的问题,用下面3种方法之一解决:
- 将所有长时间运行的查询添加到队列中,并按顺序处理这些查询。
在我的例子中,这些都是复杂的报告,然后通过电子邮件发送给客户,或者存储在永久的“临时”表中,供客户在收到通知后查看。 - 我们使用 JQuery 调用调用了一个网络服务,然后在完成时调用了一个 javascript 回发方法。
当我们不想让页面加载与 Web 服务正在执行的操作同步时,这种方法很有效。
但是,这确实意味着在长时间运行的过程完成之前,该功能不可用。 - 最复杂的一个。
我们弹出了另一个显示进度条的窗口,它还定期轮询服务器。
这使用 session 变量来确定显示进度条的距离。
启动进度条后,启动一个新线程,定期更新同一个 session 变量。
一旦 session 变量值设置为 100,弹出窗口将自行关闭。
客户喜欢这种方法。
无论如何,我希望其中之一对您有所帮助。
关于c# - 在执行长时间运行的数据库任务时处理 Web 服务超时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/522626/