lenguaje SQL, Bases de datos, Procedimientos Almacenados y SQL server

Lenguaje SQL - Bases de datos - SQL Server

    
  Buscar   

Inicio

Help Desk

Foros SQL

Tutoriales SQL
 General
 Lenguaje SQL
 SQL Server
 MySQL
 Proc. Almacenados
 Programación .NET

Manuales SQL

Libros SQL

Enlaces

Programacion

Acerca de...

Entrar
Registro

Lenguaje SQL, bases de datos y SQL Server

MSDN: U.S. Local Highlights
The latest developer information for the United States.
  • How to Control the Keyboard Using Silverlight
    This video shows you how to control your keyboard using Silverlight.

  • Sign Up Today for Free Sessions at MSDN Events
    Connect with your peers in real time! Share solutions with like-minded developers, sharpen your skills, and explore the hottest tips, tools, and technologies.

  • How Do I: Customize the Appearance of a ListBox in Windows Presentation Foundation?
    In this video, Todd Miranda shows you how to customize the ListBox in WPF.


    Last Refreshed 11/20/2008 10:37:34 PM

  •  


    Inicio > Tutoriales SQL > Procedimientos Almacenados    
    Transacciones anidadas en procedimientos almacenados

    Enviado por   el Thursday, September 09, 2004 (Her)

    En un artículo anterior hemos visto como trabajar con transacciones y con transacciones anidadas, pero eso no es todo… hay algo más…

    Las transacciones anidadas
    Recordemos como funcionan las transacciones. Tenemos 4 sentencias que son:
       • BEGIN TRAN: Comienza una transacción y aumenta en 1 @@TRANCOUNT
       • COMMIT TRAN: Reduce en 1 @@TRANCOUNT, y si @@TRANCOUNT llega a 0 guarda la transacción
       • ROLLBACK TRAN: Deshace la transacción actual, o si estamos en transacciones anidadas deshace la más externa y todas las internas. Además pone @@TRANCOUNT a 0
       • SAVE TRAN: Guarda un punto (con nombre) al que podemos volver con un ROLLBACK TRAN si es que estamos en transacciones anidadas y no queremos deshacer todo hasta la más externa.

    Un par de ejemplos dejarán las cosas más claras:

    BEGIN TRAN
    -- Primer BEGIN TRAN y ahora @@TRANCOUNT = 1
     BEGIN TRAN
     -- Ahora @@TRANCOUNT = 2
     COMMIT TRAN
     -- Volvemos a @@TRANCOUNT = 1
     -- Pero no se guarda nada ni se hacen efectivos los posibles cambios
    COMMIT TRAN
    -- Por fin @@TRANCOUNT = 0
    -- Si hubiera cambios pendientes se llevan a la base de datos
    -- Y volvemos a un estado normal con la transacción acabada

    Uso del commit

    BEGIN TRAN
    -- Primer BEGIN TRAN y @@TRANCOUNT = 1
     BEGIN TRAN
     -- Ahora @@TRANCOUNT = 2
     COMMIT TRAN
     -- Como antes @@TRANCOUNT = 1
     --Y como antes nada se guarda
     ROLLBACK TRAN
     -- Se cancela TODA la transacción. Recordemos que el COMMIT
     -- de antes no guardo nada, solo redujo @@TRANCOUNT
     -- Ahora  @@TRANCOUNT = 0
    COMMIT TRAN
    -- No vale para nada porque @@TRANCOUNT es 0 por el efecto del ROLLBACK

    Uso del rollback

    En cuanto al  SAVE TRAN podemos recordarlo con el siguiente ejemplo:

    CREATE TABLE Tabla1 (Columna1 varchar(50))
    GO
    BEGIN TRAN
    INSERT INTO Tabla1 VALUES (‘Primer valor’)
     SAVE TRAN Punto1
     INSERT INTO Tabla1 VALUES (‘Segundo valor’)
     ROLLBACK TRAN Punto1
     INSERT INTO Tabla1 VALUES (‘Tercer valor’)
    COMMIT TRAN
    SELECT * FROM Tabla1
    Columna1                                          
    --------------------------------------------------
    Primer valor
    Tercer valor
    (2 filas afectadas)

    Un ROLLBACK a un SAVE TRAN no deshace la transacción en curso ni modifica @@TRANCOUNT, simplemente cancela lo ocurrido desde el ‘SAVE TRAN nombre‘ hasta su ‘ROLLBACK TRAN nombre’

    Transacciones y procedimientos almacenados…
    Cuando trabajamos con procedimientos almacenados debemos recordar que cada procedimiento almacenado es una unidad. Cuando se ejecuta lo hace de manera independiente de quien lo llama. Sin embargo si tenemos un ROLLBACK TRAN dentro de un procedimiento almacenado cancelaremos la transacción en curso, pero si hay una transacción externa al procedimiento en el que estamos trabajando se cancelará esa transacción externa.
    Con esto no quiero decir que no se pueda usar, simplemente que hay que tener muy claras las 4 normas sobre las sentencias BEGIN, ROLLBACK y COMMIT que comentamos al principio de este artículo.
    Veamos como se comporta una transacción en un procedimiento almacenado llamado desde una transacción.

    CREATE PROCEDURE Inserta2
    AS
       BEGIN TRAN --Uno
          INSERT INTO Tabla1 VALUES ('Valor2')
       ROLLBACK TRAN --Uno
    GO
    CREATE PROCEDURE Inserta1
    AS
       BEGIN TRAN --Dos
          INSERT INTO Tabla1 VALUES ('Valor 1')
          EXEC Inserta2
          INSERT INTO Tabla1 VALUES ('Valor3')
       COMMIT TRAN --Dos
    GO

    En principio parece que si ejecutamos el procedimiento ‘Inserta1’ el resultado sería:

    EXECUTE  inserta1
    SELECT * FROM tabla1
    txt                                                
    --------------------------------------------------
    Valor1
    Valor3
    (2 filas afectadas)

    Pero lo que obtenemos es:

    EXECUTE  inserta1
    SELECT * FROM tabla1
    (1 filas afectadas)
    (1 filas afectadas)
    Servidor: mensaje 266, nivel 16, estado 2, procedimiento Inserta2, línea 8
    El recuento de transacciones después de EXECUTE indica que falta una
    instrucción COMMIT o ROLLBACK TRANSACTION. Recuento anterior = 1,
    recuento actual = 0.
    (1 filas afectadas)
    Servidor: mensaje 3902, nivel 16, estado 1, procedimiento Inserta1, línea 8
    La petición COMMIT TRANSACTION no tiene la correspondiente BEGIN TRANSACTION.
    txt                                               
    --------------------------------------------------
    Valor3
    (1 filas afectadas)

    Si analizamos estos mensajes vemos que se inserta la primera fila, se salta al segundo procedimiento almacenado y se inserta la segunda fila. Se ejecuta el ‘ROLLBACK TRAN –Dos’ del segundo procedimiento almacenado y se deshacen las dos inserciones porque este ROLLBACK cancela la transacción exterior, la del primer procedimiento almacenado.
    A continuación se termina el segundo procedimiento almacenado y como este procedimiento tiene un ‘BEGIN TRAN –Dos’ y no tiene un COMMIT o un ROLLBACK (recordemos que el ‘ROLLBACK TRAN –Dos’ termina el ‘BEGIN TRAN –Uno’) se produce un error y nos avisa que el procedimiento almacenado termina con una transacción pendiente.
    Al volver al procedimiento almacenado externo se ejecuta el INSERT que inserta la tercera fila y a continuación el ‘COMMIT TRAN –-Uno’. Aquí aparece otro error puesto que este ‘COMMIT TRAN –Uno’ estaba ahí para finalizar una transacción que ya ha sido cancelada anteriormente.

    El modo correcto
    Para que nuestras transacciones se comporten como se espera dentro de un procedimiento almacenado podemos recurrir al SAVE TRAN.
    Veamos como:

    CREATE PROCEDURE Inserta2
    AS
    SAVE TRAN Guardado
       INSERT INTO Tabla1 VALUES ('Valor2')
    ROLLBACK TRAN Guardado
    GO
    CREATE PROCEDURE Inserta1
    AS
       BEGIN TRAN
          INSERT INTO Tabla1 VALUES ('Valor 1')
          EXEC Inserta2
          INSERT INTO Tabla1 VALUES ('Valor 3')
       COMMIT TRAN
    GO

    Ahora el ‘ROLLBACK TRAN guardado’ del segundo procedimiento almacenado deshace la transacción sólo hasta el punto guardado. Además este ROLLBACK no decrementa el @@TRANCOUNT ni afecta a las transacciones en curso.
    El resultado obtenido al ejecutar este procedimiento almacenado es:

    EXECUTE  inserta1
    SELECT * FROM tabla1
    (1 filas afectadas)
    (1 filas afectadas)
    (1 filas afectadas)
    txt                                               
    --------------------------------------------------
    Valor 1
    Valor 3
    (2 filas afectadas)

    Una vez vistos estos ejemplos queda claro que no hay problema en utilizar transacciones dentro de procedimientos almacenados siempre que tengamos en cuenta el comportamiento del ROLLBACK TRAN y que utilicemos el SAVE TRAN de manera adecuada.


    Valoración Media:
     



    WEBS RECOMENDADAS
    Programacion.com
    La Web del Programador
    Talleres del Web

    Artículos más Vistos
  • ¿Como manejar las fechas en Sql Server?
    Manejar las fechas en SQL Server es una de las preguntas más recurrentes en los foros. Maximiliano Damian nos explica como tratarlas

  • INSTALACION DE MYSQL 5 EN WINDOWS (I)
    MySQL es un servidor de bases de datos que cada vez tiene más adeptos. No nos da tantas facilidades ni funcionalidades como el SQL Server, pero es una optión a tener en cuenta...

  • SQL Dinámico: Exec y sp_executeSql
    La ejecución dinámica de instrucciones SQL es una potente herramienta a la que tarde o temprano tenemos que enfrentarnos.

  • Tablas temporales en el SQL Server
    En el mundo de las bases de datos es muy común la utilización de tablas temporales. Vamos a ver com hacer buen uso de ellas...

  • FAQ: Conexión con base de datos en ASP.NET con C#
    Vamos a ver de manera sencilla como mostrar el contenido de una tabla de Access en una página Web.

  •  

    Mensajes Nuevos

  • Unificacion de Datos
    Enviado por ? el Saturday, October 04, 2008 (Her)

  • qfopbmufuq
    Enviado por ? el Wednesday, October 01, 2008 (Her)

  • fpgaedac
    Enviado por ? el Sunday, September 28, 2008 (Her)

  • GENERACION DE TABLA EN PROCEDIMIENTOS
    Enviado por EDCOTA el Friday, September 26, 2008 (Her)

  • anfbibojxl
    Enviado por ? el Friday, September 26, 2008 (Her)



  •  

    Inicio   |   Help Desk   |   Foros SQL   |   Tutoriales SQL   |   Manuales SQL   |   Libros SQL   |   Enlaces   |   Programacion   |   Acerca de...

    Lenguaje SQL - Bases de Datos - SQL Server

    Diseño Paginas Web Codice DT

    Tarot por Telefono