La arquitectura de uno de nuestros productos es una solución típica de 3 niveles:Manejo web del Servicio de Tiempos de espera mientras se realiza a largo Ejecución de tareas de base de datos
- C# cliente
- servicio web WCF
- base de datos de SQL Server
El cliente solicita información del servicio web. El servicio web accede a la base de datos para obtener la información y la devuelve al cliente.
Aquí está el problema. Algunas de estas consultas pueden llevar mucho, mucho tiempo, y no sabemos de antemano cuáles serán lentas. Sabemos que algunas son a menudo más lentas que otras, pero incluso las solicitudes más simples pueden ser lentas dado datos suficientes. A veces utiliza consultas o ejecuta informes en grandes cantidades de datos. Las consultas se pueden optimizar solo hasta el momento antes de que el volumen total de datos las ralentice.
Si una consulta en la base de datos llega al máximo tiempo de espera de consulta en el servidor SQL, la consulta de la base de datos finaliza y el servicio web devuelve un error al cliente. Esto es entendido Podemos manejar estos errores.
El cliente está esperando a que se complete la llamada del servicio web. Si la llamada a la base de datos tarda mucho tiempo, el cliente puede agotar el tiempo de espera en su llamada al servicio web. El cliente se da por vencido, pero la solicitud de la base de datos continúa el proceso. En este punto, el cliente no está sincronizado con la base de datos. La llamada a la base de datos puede tener éxito o no. Puede haber habido un error. El cliente nunca lo sabrá. En algunos casos, no deseamos que nuestros usuarios inicien otra solicitud que pueda dar como resultado un estado no válido dada la finalización de la solicitud anterior.
Tengo curiosidad por ver cómo otros han manejado este problema. ¿Qué estrategias ha utilizado para evitar que los tiempos de espera del servicio web afecten las llamadas a la base de datos?
Las mejores ideas que se me ocurren son: crear una capa de base de datos real en algún lugar, dentro del servicio web, adjunta a una cola de mensajes, algo. La descarga de cada consulta a otro proceso parece excesiva. (Por otra parte, no siempre sabemos si una solicitud determinada será rápida o lenta.)
Sería genial si pudiéramos separar el acto de realizar una solicitud HTTP desde el acto de iniciar y ejecutar un proceso de base de datos . He visto esto hecho con un servidor personalizado en una compañía anterior, pero estaba usando una comunicación directa de socket, y prefiero evitar reemplazar el servicio web con alguna aplicación personalizada.
Tenga en cuenta que dada la cantidad de datos que manejamos, estamos en la optimización de la consulta. La optimización de consultas, los índices, etc., solo lo lleva tan lejos cuando el volumen de datos es alto. A veces las cosas solo toman mucho tiempo.