Архитектура одного из наших продуктов является типичным 3-уровневым решением:
- Клиент С#
- Веб-сервис WCF
- База данных SQL Server
Клиент запрашивает информацию из веб-сервиса. Веб-сервис обращается к базе данных за информацией и возвращает ее клиенту.
Здесь проблема. Некоторые из этих запросов могут занимать очень много времени, и мы не знаем заранее, какие из них будут медленными. Мы знаем некоторые, которые часто медленнее других, но даже самые простые запросы могут быть медленными при наличии достаточного количества данных. Иногда используется запрос или запуск отчетов на больших объемах данных. Запросы могут быть оптимизированы только до тех пор, пока объем данных не замедлит их.
Если запрос в базе данных достигает максимального времени ожидания запроса на сервере SQL, запрос к базе данных прекращается, и веб-служба возвращает ошибку клиенту. Это понятно. Мы можем справиться с этими ошибками.
Клиент ожидает завершения вызова веб-службы. Если вызов базы данных занимает много времени, клиент может прервать тайм-аут при обращении к веб-службе. Клиент сдается, но запрос к базе данных продолжает обрабатываться. В этот момент клиент не синхронизирован с базой данных. Вызов базы данных может или не может быть успешным. Возможно, произошла ошибка. Клиент никогда не узнает. В некоторых случаях мы не хотим, чтобы наши пользователи инициировали другой запрос, который может привести к недопустимому состоянию при завершении предыдущего запроса.
Мне любопытно посмотреть, как другие справились с этой проблемой. Какие стратегии вы использовали для предотвращения влияния времени ожидания веб-службы на вызовы базы данных?
Лучшие идеи, которые я могу придумать, включают создание фактического слоя базы данных somewhere-- внутри веб-службы, прикрепленного к сообщению queue--. Выгрузка каждого отдельного запроса в другой процесс кажется чрезмерной. (Опять же, мы не всегда знаем, будет ли данный запрос быстрым или медленным.)
Было бы замечательно, если бы мы могли отделить процесс создания HTTP-запроса от процесса запуска и запуска процесса базы данных. Я видел, как это было сделано с пользовательским сервером в предыдущей компании, но он использовал прямую связь через сокет, и я бы предпочел не заменять веб-сервис каким-либо пользовательским приложением.
Обратите внимание, что с учетом объема данных, с которыми мы имеем дело, мы полностью оптимизируем запросы. Оптимизация запросов, индексы и т.д. Делают это только тогда, когда объем данных велик. Иногда все просто занимает много времени.