Qual é o benefício de usar SET XACT_ABORT ON
em um procedimento armazenado?
sql
sql-server
odiseh
fonte
fonte
Respostas:
SET XACT_ABORT ON
instrui o SQL Server a reverter toda a transação e abortar o lote quando ocorrer um erro em tempo de execução. Ele cobre você em casos como um tempo limite de comando que ocorre no aplicativo cliente, e não no próprio SQL Server (que não é coberto pelaXACT_ABORT OFF
configuração padrão ).Como o tempo limite da consulta deixará a transação aberta,
SET XACT_ABORT ON
é recomendado em todos os procedimentos armazenados com transações explícitas (a menos que você tenha um motivo específico para fazer outra coisa), pois as conseqüências de um aplicativo que executa o trabalho em uma conexão com uma transação aberta são desastrosas.Há uma excelente visão geral no blog de Dan Guzman ,
fonte
BEGIN TRY
-BEGIN CATCH
eROLLBACK
com oBEGIN CATCH
bloco no Sql?BEGIN TRY
-BEGIN CATCH
não captura coisas como um tempo limite no aplicativo cliente, e alguns erros SQL também são impossíveis de rastrear , deixando uma transação aberta em que você não esperaria uma.Na minha opinião, SET XACT_ABORT ON foi tornado obsoleto pela adição de BEGIN TRY / BEGIN CATCH no SQL 2k5. Antes dos blocos de exceção no Transact-SQL, era realmente difícil lidar com erros e os procedimentos desequilibrados eram muito comuns (procedimentos que tinham uma @@ TRANCOUNT diferente na saída em comparação à entrada).
Com a adição do tratamento de exceção Transact-SQL, é muito mais fácil escrever procedimentos corretos que garantem o equilíbrio adequado das transações. Por exemplo, eu uso este modelo para manipulação de exceção e transações aninhadas :
Isso me permite escrever procedimentos atômicos que revertem apenas seu próprio trabalho em caso de erros recuperáveis.
Um dos principais problemas enfrentados pelos procedimentos Transact-SQL é a pureza dos dados : algumas vezes, os parâmetros recebidos ou os dados nas tabelas estão completamente errados, resultando em erros de chave duplicados, erros de restrição referenciais, erros de verificação de restrição e assim por diante. Afinal, esse é exatamente o papel dessas restrições, se esses erros de pureza dos dados fossem impossíveis e todos capturados pela lógica de negócios, as restrições seriam todas obsoletas (exagero dramático adicionado para efeito). Se XACT_ABORT estiver ativado, todos esses erros resultarão na perda de toda a transação, em vez de poder codificar blocos de exceção que manipulam a exceção normalmente. Um exemplo típico é tentar fazer um INSERT e reverter para uma violação UPDATE on PK.
fonte
Citando o MSDN :
Na prática, isso significa que algumas das instruções podem falhar, deixando a transação 'parcialmente concluída', e pode não haver sinal dessa falha para um chamador.
Um exemplo simples:
Esse código seria executado 'com êxito' com XACT_ABORT OFF e terminará com um erro com XACT_ABORT ON ('INSERT INTO t2' não será executado e um aplicativo cliente gerará uma exceção).
Como uma abordagem mais flexível, você pode verificar @@ ERROR após cada instrução (old school) ou usar os blocos TRY ... CATCH (MSSQL2005 +). Pessoalmente, prefiro definir XACT_ABORT ON sempre que não houver motivo para algum tratamento avançado de erros.
fonte
Com relação aos tempos limite do cliente e ao uso de XACT_ABORT para manipulá-los, na minha opinião, há pelo menos um motivo muito bom para ter tempos limites nas APIs do cliente, como SqlClient, e que é para proteger o código do aplicativo cliente contra conflitos que ocorrem no código do servidor SQL. Nesse caso, o código do cliente não tem falhas, mas deve se proteger de um bloqueio permanente, aguardando a conclusão do comando no servidor. Por outro lado, se houver um tempo limite do cliente para proteger o código do cliente, o XACT_ABORT ON precisará proteger o código do servidor contra as interrupções do cliente, caso o código do servidor demore mais para ser executado do que o cliente está disposto a esperar.
fonte
É usado no gerenciamento de transações para garantir que quaisquer erros resultem na reversão da transação.
fonte