none
Problemas con Rollback RRS feed

  • Pregunta

  • Hola Grupo,

       Tengo la siguiente codificación en un PA (procedimiento almacenado), el cual al ejecutarlo cuelga la BD ya que al parecer no llega al Rollback. Favor cómo puedo mejorar la instrucción para que realice el rollback.

    DECLARE @MsgRetorno NVARCHAR(255)
    SET @MsgRetorno = 'True'

    BEGIN TRAN cm_voluntarios_validar
     
       BEGIN TRY
     
               INSERT INTO ignore
               SELECT GETDATE(),'juan'  (aquí lo insertara correctamente)
       
       
              INSERT INTO ignores  (esta tabla no existe, por ende debe caerse y gatillar el rollbak, pero cuelga la tabla)
              SELECT GETDATE(),'pablo'

     
           COMMIT TRAN cm_voluntarios_validar

        END TRY

       BEGIN CATCH
             SET @MsgRetorno = 'Error en la Base de Datos: ' + ERROR_MESSAGE() + ', en la línea ' + CONVERT(NVARCHAR

              (255),  ERROR_LINE() ) + '.'
            ROLLBACK TRAN cm_voluntarios_validar
        END CATCH
     
     SELECT @MsgRetorno

     

    martes, 4 de octubre de 2016 18:26

Respuestas

  • Gracias por tu respuesta, era lo que imaginaba, sin embargo, existe alguna forma de evitar esto si por error se crea un objeto que no existe dentro del procedimiento.

    Primero dejar claro que una transacción no valida ni controla la existencia de un objeto dentro de un contexto, quizá podría esperarse que dicha labor la realice el controlador de errores TRY-CACTH pero tampoco lo hace, por lo menos no de la forma como lo planteas.

    Intenta ejecutar la siguiente consulta:

    BEGIN TRY      
        SELECT * FROM T;
    END TRY  
    BEGIN CATCH  
        SELECT ERROR_MESSAGE();  
    END CATCH  


    Obtendrás el siguiente error:

    Mens. 208, Nivel 16, Estado 1, Línea 17
    El nombre de objeto 'T' no es válido.

    Sin embargo, el bloque CATCH podría capturar el error si esté se origina en un contexto inferior, por ejemplo:

    CREATE PROCEDURE dbo.TablaNoExiste
    AS  
        SELECT * FROM T;  
    GO
    
    BEGIN TRY      
        EXECUTE dbo.TablaNoExiste
    END TRY  
    BEGIN CATCH  
        SELECT 'Mi error: ' + ERROR_MESSAGE() AS Mensaje;  
    END CATCH  
    GO

    En este caso el error se produce en un nivel inferior al bloque TRY por tanto el bloque CATCH lo capturará



    Espero que la información proporcionada te haya sido de utilidad, quedo atento a tus comentarios.
    martes, 4 de octubre de 2016 23:08
  • Como ya mencionaron antes, el bloque TRY-CATCH no captura errores de compilacion que ocurren durante la ejecucion. Estos errores suelen pasar debido a que SQL Server usa "deferred name resolution" o resolucion diferida de nombres y lo cual permite que un procedimiento haga referencia a objetos no existentes durante su creacion pero que son chequeados durante la ejecucion.

    La forma de lidear con este tipo de errores es llamando al procedimiento dentro de un bloque TRY-CATCH.

    Aca te paso un articulo detallado que te ayudara a comprender mejor todo lo relacionado con captura de errores en T-SQL.

    http://www.sommarskog.se/error_handling/Part1.html


    AMB

    Some guidelines for posting questions...

    AYÚDANOS A AYUDARTE, guía básica de consejos para formular preguntas


    miércoles, 5 de octubre de 2016 12:48

Todas las respuestas

  • jogc,

    Una transacción gestiona la atomicidad, consistencia, aislamiento y durabilidad (ACID), de no cumplir con cualquiera de los requisitos todas las operaciones se revierten dejando a la base de datos en un estado de consistencia. Sin embargo, lo que muestras es un error de sintaxis, un objeto que no existe en la base de datos, la consulta que muestras ni siquiera se ejecuta, no es de esperar que el manejo de transacciones advierta que el objeto no exista en el contexto actual.


    Espero que la información proporcionada te haya sido de utilidad, quedo atento a tus comentarios.
    martes, 4 de octubre de 2016 18:48
  • Gracias por tu respuesta, era lo que imaginaba, sin embargo, existe alguna forma de evitar esto si por error se crea un objeto que no existe dentro del procedimiento.
    martes, 4 de octubre de 2016 19:36
  • Gracias por tu respuesta, era lo que imaginaba, sin embargo, existe alguna forma de evitar esto si por error se crea un objeto que no existe dentro del procedimiento.

    Primero dejar claro que una transacción no valida ni controla la existencia de un objeto dentro de un contexto, quizá podría esperarse que dicha labor la realice el controlador de errores TRY-CACTH pero tampoco lo hace, por lo menos no de la forma como lo planteas.

    Intenta ejecutar la siguiente consulta:

    BEGIN TRY      
        SELECT * FROM T;
    END TRY  
    BEGIN CATCH  
        SELECT ERROR_MESSAGE();  
    END CATCH  


    Obtendrás el siguiente error:

    Mens. 208, Nivel 16, Estado 1, Línea 17
    El nombre de objeto 'T' no es válido.

    Sin embargo, el bloque CATCH podría capturar el error si esté se origina en un contexto inferior, por ejemplo:

    CREATE PROCEDURE dbo.TablaNoExiste
    AS  
        SELECT * FROM T;  
    GO
    
    BEGIN TRY      
        EXECUTE dbo.TablaNoExiste
    END TRY  
    BEGIN CATCH  
        SELECT 'Mi error: ' + ERROR_MESSAGE() AS Mensaje;  
    END CATCH  
    GO

    En este caso el error se produce en un nivel inferior al bloque TRY por tanto el bloque CATCH lo capturará



    Espero que la información proporcionada te haya sido de utilidad, quedo atento a tus comentarios.
    martes, 4 de octubre de 2016 23:08
  • Como ya mencionaron antes, el bloque TRY-CATCH no captura errores de compilacion que ocurren durante la ejecucion. Estos errores suelen pasar debido a que SQL Server usa "deferred name resolution" o resolucion diferida de nombres y lo cual permite que un procedimiento haga referencia a objetos no existentes durante su creacion pero que son chequeados durante la ejecucion.

    La forma de lidear con este tipo de errores es llamando al procedimiento dentro de un bloque TRY-CATCH.

    Aca te paso un articulo detallado que te ayudara a comprender mejor todo lo relacionado con captura de errores en T-SQL.

    http://www.sommarskog.se/error_handling/Part1.html


    AMB

    Some guidelines for posting questions...

    AYÚDANOS A AYUDARTE, guía básica de consejos para formular preguntas


    miércoles, 5 de octubre de 2016 12:48
  • Muy buena respuesta.

    Solo clarificar que no es un error de sintaxis (la sentencia esta bien sintacticamente) sino de compilación. Como mencione en mi respuesta, SQL Server hace uso de la resolución diferida de nombres, lo cual permite que se pueda crear un procedimiento que haga referencia a objetos no existentes y los cuales son chequeados durante la ejecucion.


    AMB

    Some guidelines for posting questions...

    AYÚDANOS A AYUDARTE, guía básica de consejos para formular preguntas

    miércoles, 5 de octubre de 2016 13:33