Puntos de almacenamiento de transacciones

Los puntos de almacenamiento ofrecen un mecanismo para revertir partes de una transacción. Puede crear un punto de almacenamiento mediante la instrucción SAVE TRANSACTION savepoint_name. Más adelante, ejecute una instrucción ROLLBACK TRANSACTION savepoint_name para revertir al punto de almacenamiento en vez de revertir al inicio de la transacción.

Los puntos de almacenamiento son útiles en situaciones en que no es probable que se produzcan errores. El uso de un punto de almacenamiento para revertir parte de una transacción en caso de producirse un error no frecuente puede resultar más eficaz que hacer que cada transacción pruebe si una actualización es válida antes de realizarla. Las operaciones de actualizar y revertir son costosas, por lo que los puntos de almacenamiento sólo son eficaces si la probabilidad de encontrar un error es baja y el costo de comprobar la validez de una actualización de antemano es relativamente alto.

En este ejemplo se muestra la utilización de un punto de almacenamiento en un sistema de pedidos en el que hay pocas probabilidades de agotar las existencias debido a que la compañía tiene proveedores eficaces y puntos de nuevo pedido. Normalmente, una aplicación comprobaría que hay suficientes existencias antes de intentar realizar las actualizaciones que registran el pedido. Este ejemplo supone que, por algún motivo, comprobar de antemano la cantidad disponible en las existencias es relativamente costoso (debido a una conexión sobre un módem o WAN lentos). Se podría codificar la aplicación para que realizara sólo la actualización y, si se produjera un error que indicara que no hay existencias suficientes, revirtiera la actualización. En este caso, una comprobación de @@ERROR tras la inserción es más rápido que comprobar la cantidad antes de la actualización.

La tabla InvCtrl contiene una restricción CHECK que desencadena el error 547 si el valor de la columna QtyInStk es menor que 0. El procedimiento OrderStock crea un punto de almacenamiento. Si se produce el error 547, revierte hasta el punto de almacenamiento y devuelve el número de elementos disponibles al proceso que realiza la llamada. Éste puede entonces reemplazar el pedido por la cantidad disponible. Si OrderStock devuelve 0, el proceso que realiza la llamada certifica que había suficientes existencias disponibles para satisfacer el pedido.

SET NOCOUNT OFF;
GO
USE AdventureWorks;
GO
CREATE TABLE InvCtrl
    (WhrhousID      int,
    PartNmbr      int,
    QtyInStk      int,
    ReordrPt      int,
    CONSTRAINT InvPK PRIMARY KEY
    (WhrhousID, PartNmbr),
    CONSTRAINT QtyStkCheck CHECK (QtyInStk > 0) );
GO
CREATE PROCEDURE OrderStock
    @WhrhousID int,
    @PartNmbr int,
    @OrderQty int
AS
    DECLARE @ErrorVar int;
    SAVE TRANSACTION StkOrdTrn;
    UPDATE InvCtrl SET QtyInStk = QtyInStk - @OrderQty
        WHERE WhrhousID = @WhrhousID
        AND PartNmbr = @PartNmbr;
    SELECT @ErrorVar = @@error;
    IF (@ErrorVar = 547)
    BEGIN
        ROLLBACK TRANSACTION StkOrdTrn;
        RETURN (SELECT QtyInStk
                FROM InvCtrl
                WHERE WhrhousID = @WhrhousID
                AND PartNmbr = @PartNmbr);
    END
    ELSE
        RETURN 0;
GO

Vea también

Otros recursos

ROLLBACK TRANSACTION (Transact-SQL)
SAVE TRANSACTION (Transact-SQL)

Ayuda e información

Obtener ayuda sobre SQL Server 2005