¿Cuál es la ventaja de usar SET XACT_ABORT ON
en un procedimiento almacenado?¿Cuál es la ventaja de usar "SET XACT_ABORT ON" en un procedimiento almacenado?
Respuesta
SET XACT_ABORT ON
indica a SQL Server que revierte la transacción completa y anule el lote cuando se produce un error en tiempo de ejecución. Se le cubre en casos como un tiempo de espera de comandos que ocurren en la aplicación cliente en lugar de dentro de SQL Server en sí (que no está cubierta por la configuración predeterminada XACT_ABORT OFF
.)
Desde un tiempo de espera de consulta saldrá de la transacción abierta, se recomienda SET XACT_ABORT ON
en todos los procedimientos almacenados con transacciones explícitas (a menos que tenga una razón específica para hacer lo contrario) ya que las consecuencias de una aplicación que realiza el trabajo en una conexión con una transacción abierta son desastrosas.
Hay una muy buena visión general sobre Dan Guzman's Blog,
¿por qué no está activado por defecto? –
Se utiliza en la gestión de transacciones para garantizar que los errores provoquen que la transacción se retrotraiga.
En mi opinión SET EN XACT_ABORT se hizo obsoleto por la adición de COMENZAR TRY/CATCH COMENZAR en 2k5 SQL. Antes de los bloques de excepción en Transact-SQL era muy difícil manejar los errores y los procedimientos desequilibrados eran demasiado comunes (procedimientos que tenían un @@ TRANCOUNT diferente en la salida en comparación con la entrada).
Con la adición del manejo de excepciones de Transact-SQL es mucho más fácil escribir procedimientos correctos que garanticen un equilibrio adecuado de las transacciones. Por ejemplo, yo uso este template for exception handling and nested transactions:
create procedure [usp_my_procedure_name]
as
begin
set nocount on;
declare @trancount int;
set @trancount = @@trancount;
begin try
if @trancount = 0
begin transaction
else
save transaction usp_my_procedure_name;
-- Do the actual work here
lbexit:
if @trancount = 0
commit;
end try
begin catch
declare @error int, @message varchar(4000), @xstate int;
select @error = ERROR_NUMBER(), @message = ERROR_MESSAGE(), @xstate = XACT_STATE();
if @xstate = -1
rollback;
if @xstate = 1 and @trancount = 0
rollback
if @xstate = 1 and @trancount > 0
rollback transaction usp_my_procedure_name;
raiserror ('usp_my_procedure_name: %d: %s', 16, 1, @error, @message) ;
end catch
end
go
Me permite escribir procedimientos atómicos que sólo retrotracción su propio trabajo en caso de errores recuperables.
Uno de los principales problemas que enfrentan los procedimientos de Transact-SQL es la pureza de datos : a veces los parámetros recibidos o los datos de las tablas son simplemente errónea, lo que resulta en errores de clave duplicados, referencial limitan errores, comprobar limitar los errores y por lo tanto y así sucesivamente. Después de todo, esa es exactamente la función de estas restricciones, si estos errores de pureza de datos fueran imposibles y todos atrapados por la lógica comercial, las restricciones quedarían obsoletas (se agregará una exageración dramática para el efecto). Si XACT_ABORT está activado, todos estos errores provocan que se pierda toda la transacción, en lugar de poder codificar los bloques de excepciones que manejan la excepción correctamente. Un ejemplo típico es tratar de hacer un INSERTO y volver a una ACTUALIZACIÓN sobre la violación de PK.
Excepto por los tiempos de espera de los clientes ... y mi opinión es que SET XACT_ABORT es más efectivo en SQL 2005 porque el comportamiento es más predecible: muchos menos errores de interrupción de lotes. – gbn
* los tiempos de espera del cliente * son errores de la aplicación. Ninguna aplicación debería imponer un tiempo de espera de comando, nunca. Es una práctica terriblemente pobre que el tiempo de espera de SqlClient predeterminado me da un dolor de cabeza cada vez que pienso cómo podrían enviar algo así. Puede guiar todo el manejo de errores de Transact-SQL alrededor del problema de tiempo de espera, o puede codificar al cliente correctamente y solucionar los problemas de negocios en el manejo de errores. Por supuesto, mi punto de vista es desde el punto de vista de un desarrollador. los que están en el rol de administrador/dba generalmente ven el mundo de manera diferente, dado que están atrapados con las aplicaciones que otros crean. –
Estoy de acuerdo, pero planeo mi manejo de errores en todas las eventualidades, porque sé que me echarán la culpa como Desarrollador DBA si se produce un tiempo de espera de comando. – gbn
Citando MSDN:
Cuando SET XACT_ABORT está en ON, si una instrucción de Transact-SQL genera un error en tiempo de ejecución, toda la transacción se termina y deshace. Cuando SET XACT_ABORT está desactivado, en algunos casos solo se retrotrae la instrucción de Transact-SQL que generó el error y la transacción continúa procesándose.
En la práctica esto significa que algunas de las declaraciones pueden fallar, dejando la transacción "parcialmente completada", y puede que no haya indicios de esta falla para la persona que llama.
Un ejemplo sencillo:
INSERT INTO t1 VALUES (1/0)
INSERT INTO t2 VALUES (1/1)
SELECT 'Everything is fine'
Este código se ejecute 'éxito' con XACT_ABORT OFF, y se terminará con un error con XACT_ABORT ON ('INSERT INTO t2' no se ejecutará, y una aplicación cliente levantará una excepción).
Como un enfoque más flexible, puede marcar @@ ERROR después de cada instrucción (vieja escuela), o usar bloques TRY ... CATCH (MSSQL2005 +). Personalmente, prefiero configurar XACT_ABORT cuando no haya motivos para un manejo avanzado de errores.
En cuanto a los tiempos de espera del cliente y el uso de XACT_ABORT para manejarlos, en mi opinión hay al menos una muy buena razón para tener tiempos de espera en las API del cliente como SqlClient, y es proteger el código de aplicación del cliente de interbloqueos en SQL código del servidor En este caso, el código del cliente no tiene ninguna falla, pero tiene que protegerse del bloqueo para siempre esperando que el comando se complete en el servidor. Por lo tanto, si los tiempos de espera de los clientes deben existir para proteger el código del cliente, XACT_ABORT ON debe proteger el código del servidor de los abortos del cliente, en caso de que el código del servidor tarde más en ejecutarse de lo que el cliente está dispuesto a esperar.
- 1. ¿Cuál es el alcance de SET IDENTITY_INSERT xyz ON?
- 2. ¿Cuál es la mejor manera de probar un procedimiento almacenado?
- 3. ¿Cuál es la sintaxis para definir un procedimiento de Oracle dentro de otro procedimiento almacenado?
- 4. Usar el cursor en un bucle de un procedimiento almacenado
- 5. ¿Cuál es la longitud máxima de un parámetro de cadena para el procedimiento Almacenado?
- 6. ¿Cuál es la ventaja de usar memset() en C
- 7. ¿Cuál es la ventaja de usar métodos estáticos en Python?
- 8. Ejecutar un procedimiento almacenado dentro de un procedimiento almacenado
- 9. ¿Cómo usar un valor de un procedimiento almacenado en otro?
- 10. Usar la base de datos dentro de un procedimiento almacenado
- 11. ¿Cuál es la ventaja de usar varbinary sobre varchar aquí?
- 12. ¿Cuál es exactamente la ventaja de usar Punjab
- 13. ¿Cuál es la ventaja de usar filter_has_var() sobre isset()
- 14. Cuenta de devolución en el procedimiento almacenado
- 15. ¿Cuál es la ventaja de usar Python Virtualbox API?
- 16. ¿Usar la función como parámetro al ejecutar un procedimiento almacenado?
- 17. Desaparición del procedimiento almacenado
- 18. Cómo llamar a un procedimiento almacenado desde otro procedimiento almacenado?
- 19. Procedimiento almacenado NULL Parámetro
- 20. Procedimiento almacenado al ejecutar otro procedimiento almacenado
- 21. ¿Cómo devuelvo XML de un procedimiento almacenado?
- 22. Transacción de procedimiento almacenado
- 23. ¿Cómo implementar un procedimiento almacenado condicional Upsert?
- 24. ¿Cuál es la ventaja de usar un ObjectId en lugar de un String simple?
- 25. Llamar a un procedimiento almacenado en un procedimiento almacenado en MySQL
- 26. MS SQL: Suprime el valor devuelto del procedimiento almacenado llamado en el procedimiento almacenado
- 27. Nombre de objeto inválido - Procedimiento almacenado
- 28. la salida de un procedimiento almacenado
- 29. procedimiento almacenado devuelve varchar
- 30. ¿Cuál es la ventaja de Jikes RVM
msdn ref para su comodidad: https://msdn.microsoft.com/en-us/library/ms188792.aspx –