Transaction Savepoints

Savepoints offer a mechanism to roll back portions of transactions. You create a savepoint using the SAVE TRANSACTION savepoint_name statement, then later execute a ROLLBACK TRANSACTION savepoint_name statement to roll back to the savepoint instead of rolling back to the start of a transaction.

Savepoints are useful in situations where errors are unlikely to occur. The use of a savepoint to roll back part of a transaction in the case of an infrequent error can be more efficient than having each transaction test to see if an update is valid before making the update. Updates and rollbacks are expensive operations, so savepoints are effective only if the probability of encountering the error is low and the cost of checking the validity of an update beforehand is relatively high.

This example shows the use of a savepoint in an order system in which there is a low probability of running out of stock because the company has effective suppliers and reorder points. Usually an application would verify that there is enough stock on hand before attempting to make the updates that would record the order. This example assumes that, for some reason (such as connecting over a slow modem or WAN), first verifying the quantity of stock available is relatively expensive. The application could be coded to just make the update, and if it gets an error indicating that there is not enough stock, it rolls back the update. In this case, a quick check of @@ERROR after the insert is much faster than verifying the amount before the update.

The InvCtrl table has a CHECK constraint that triggers a 547 error if the QtyInStk column goes below 0. The OrderStock procedure creates a savepoint. If a 547 error occurs, it rolls back to the savepoint and returns the number of items on hand to the calling process. The calling process can then decide if it wants to replace the order for the quantity on hand. If OrderStock returns a 0, the calling process knows there was enough stock on hand to satisfy the order.

SET NOCOUNT OFF

GO

USE pubs

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 = 1

    AND PartNmbr = 1

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

  

See Also
ROLLBACK TRANSACTION SAVE TRANSACTION

  


(c) 1988-98 Microsoft Corporation. All Rights Reserved.