sql >> Base de Datos >  >> RDS >> Sqlserver

Ocasionalmente Obtener SqlException:Tiempo de espera expirado

Debe investigar esto en el lado del servidor para comprender por qué se agota el tiempo de ejecución. Tenga en cuenta que el servidor no tiene tiempo de espera, el tiempo de espera se debe a los 30 segundos predeterminados en SqlCommand.CommandTimeout .

Un buen recurso es Esperas y colas , que es una metodología para diagnosticar cuellos de botella en el rendimiento con SQL Server. Según la causa real del tiempo de espera, se pueden tomar las medidas adecuadas. Debe establecer ante todo si se trata de una ejecución lenta (un mal plan) o de un bloqueo.

Si me atrevo a adivinar, diría que el patrón poco saludable de IF EXISTS... UPDATE es la causa raíz. Este patrón es incorrecto y provocará errores en la concurrencia. Dos transacciones simultáneas que ejecutan IF EXISTS simultáneamente ambos llegarán a la misma conclusión y ambos intentar INSERT o UPDATE . Dependiendo de las restricciones existentes en la base de datos, puede terminar con un interbloqueo (el caso afortunado) o con una escritura perdida (el caso desafortunado). Sin embargo, solo una investigación adecuada revelaría la causa raíz real. Podría ser algo totalmente diferente, como eventos de crecimiento automático .

Su procedimiento también está manejando incorrectamente el bloque CATCH. Debes siempre compruebe el XACT_STATE() porque es posible que la transacción ya se haya revertido en el momento en que se ejecuta el bloque CATCH. Tampoco está claro lo que espera del nombre de la transacción, este es un error común que veo a menudo asociado con confundir las transacciones nombradas con los puntos de guardado. Para ver un patrón correcto, consulte Gestión de excepciones y transacciones anidadas .

Editar

Aquí hay una posible manera de investigar esto:

  1. Cambie el CommandTimeout a 0 (es decir, infinito).
  2. Habilite el blocked process threshold , configúrelo en 30 segundos (el antiguo CommandTimeout)
  3. Supervisar en Profiler para Evento de informe de proceso bloqueado
  4. Comienza tu carga de trabajo
  5. Vea si Profiler produce algún evento de informe. Si es así, identificarán la causa.

Estas acciones generarán un evento de 'informe de proceso bloqueado' cada vez que haya obtenido un tiempo de espera, si el tiempo de espera fue causado por un bloqueo. Su aplicación continuará esperando hasta que se elimine el bloqueo, si el bloqueo es causado por un bloqueo en vivo entonces esperará para siempre.