¿Cuál es una buena manera de hacer que los procesos almacenados sean lo suficientemente robustos como para que puedan escalar muy bien y también contener el manejo de errores?
Además, ¿cuál es la mejor manera de manejar múltiples escenarios de error en un proceso almacenado y tener un sistema de retroalimentación inteligente que devolverá información de error significativa a las aplicaciones de llamada?
Respuestas:
Alex Kuznetsov tiene un excelente capítulo en su libro Defensive Database Programming (Capítulo 8) que cubre T-SQL TRY ... CATCH, transacciones T-SQL y configuración de SET XACT_ABORT, y utiliza el manejo de errores del lado del cliente. Le ayudará mucho a decidir cuál de las opciones tiene más sentido para lo que necesita lograr.
Está disponible de forma gratuita en este sitio . De ninguna manera estoy afiliado a la compañía, pero soy dueño de la versión impresa de ese libro.
Hay muchos pequeños detalles sobre este tema que Alex explica muy bien.
Por solicitud de Nick ... (pero no todo esto está en el capítulo)
En términos de escalado, debe ser brutalmente honesto acerca de qué actividades deben estar en el código db y cuáles deben estar en la aplicación. ¿Alguna vez notó cómo el código de ejecución rápida tiende a volver a diseñar para una sola preocupación por método?
La forma más fácil de comunicarse sería con códigos de error personalizados (> 50,000). También es bastante rápido. Significa que tendría que mantener el código db y el código de la aplicación sincronizados. Con un código de error personalizado, también puede devolver información útil en la cadena del mensaje de error. Debido a que tiene un código de error estrictamente para esa situación, puede escribir un analizador en el código de la aplicación adaptado al formato de datos del error.
Además, ¿qué condiciones de error necesitan lógica de reintento en la base de datos? Si desea volver a intentarlo después de X segundos, es mejor que lo maneje en el código de la aplicación para que la transacción no se bloquee tanto. Si solo vuelve a enviar una operación DML de inmediato, repetirla en el SP podría ser más eficiente. Sin embargo, tenga en cuenta que posiblemente tendrá que duplicar el código o agregar una capa de SP para lograr un nuevo intento.
Realmente, ese es actualmente el mayor problema con la lógica TRY ... CATCH en SQL Server en este momento. Se puede hacer, pero es un poco tonto. Busque algunas mejoras para esto en SQL Server 2012, especialmente para volver a lanzar excepciones del sistema (preservar el número de error original). Además, hay FORMATMESSAGE , que agrega cierta flexibilidad en la construcción de mensajes de error, especialmente para fines de registro.
fuente
Esta es nuestra plantilla (registro de errores eliminado)
Notas:
... así que no cree más TXN de los que necesita
Sin embargo,
fuente
Uso Try / Catch, pero también recopilo tanta información como sea posible y la escribo en un registro de errores DESPUÉS de la reversión. En este ejemplo, "LogEvent" es un procedimiento almacenado que escribe en una tabla EventLog, que contiene los detalles de lo que sucedió. GetErrorInfo () es una llamada de función que devuelve el mensaje de error exacto.
Cuando se produce un error, se recopila la información, el procedimiento salta a la sección de manejo de errores y emite una reversión. La información se escribe en el registro, luego sale el procedimiento.
Teniendo en cuenta las llamadas de procedimiento / función adicionales involucradas, parece un poco exagerado. SIN EMBARGO, este método es tremendamente útil cuando se trata de depurar el problema.
fuente