Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

TSQL Try/Catch dentro da transação ou vice-versa?


Só abra uma transação quando estiver dentro do TRY block e logo antes da declaração real, e confirme-a imediatamente. Não espere seu controle ir até o final do lote para confirmar suas transações.

Se algo der errado enquanto você estiver no TRY bloco e você abriu uma transação, o controle saltará para o CATCH quadra. Simplesmente reverta sua transação lá e faça outro tratamento de erros conforme necessário.

Adicionei um pequeno cheque para qualquer transação aberta usando @@TRANCOUNT antes de realmente reverter a transação. Não faz muito sentido neste cenário. É mais útil quando você está fazendo algumas verificações de validação em seu TRY bloco antes de abrir uma transação, como verificar valores de parâmetros e outras coisas e gerar erro no TRY bloquear se alguma das verificações de validação falhar. Nesse caso, o controle pulará para o CATCH bloquear sem sequer abrir uma transação. Lá você pode verificar qualquer transação aberta e reverter se houver alguma aberta. No seu caso, você realmente não precisa verificar nenhuma transação aberta, pois não inserirá o CATCH bloquear a menos que algo dê errado dentro de sua transação.

Não pergunte depois de ter executado o DELETE operação se ela precisa ser confirmada ou revertida; faça todas essas validações antes de abrir a transação. Uma vez que uma transação é aberta, confirme-a imediatamente e, em caso de erros, faça o tratamento de erros (você está fazendo um bom trabalho obtendo informações detalhadas usando quase todas as funções de erro).
BEGIN TRY

  BEGIN TRANSACTION SCHEDULEDELETE
    DELETE   -- delete commands full SQL cut out
    DELETE   -- delete commands full SQL cut out
    DELETE   -- delete commands full SQL cut out
 COMMIT TRANSACTION SCHEDULEDELETE
    PRINT 'X rows deleted. Operation Successful Tara.' --calculation cut out.
END TRY

BEGIN CATCH 
  IF (@@TRANCOUNT > 0)
   BEGIN
      ROLLBACK TRANSACTION SCHEDULEDELETE
      PRINT 'Error detected, all changes reversed'
   END 
    SELECT
        ERROR_NUMBER() AS ErrorNumber,
        ERROR_SEVERITY() AS ErrorSeverity,
        ERROR_STATE() AS ErrorState,
        ERROR_PROCEDURE() AS ErrorProcedure,
        ERROR_LINE() AS ErrorLine,
        ERROR_MESSAGE() AS ErrorMessage
END CATCH