保存點提供了一種機制,用于回滾部分事務??梢允褂?SAVE TRANSACTION savepoint_name 語句創建一個保存點,然后再執行 ROLLBACK TRANSACTION savepoint_name 語句回滾到該保存點,從而無須回滾到事務的開始。
在不可能發生錯誤的情況下,保存點很有用。在很少出現錯誤的情況下使用保存點回滾部分事務,比讓每個事務在更新之前測試更新的有效性更為有效。更新和回滾操作代價很大,因此只有在遇到錯誤的可能性很小,而且預先檢查更新的有效性的代價相對很高的情況下,使用保存點才會非常有效。
下面的示例顯示保存點在一個訂購系統中的使用情況。該系統中存貨不足的可能性很小,因為該公司具備有效的供應商和再訂購點。通常應用程序在嘗試更新訂購記錄時,會先驗證手邊是否有足夠的存貨。該示例假定由于某種原因(如連接到一個低速的調制解調器或廣域網上),先驗證可用存貨的數量代價相對較大??蓪贸绦蚓帉憺橹贿M行更新,而且如果收到錯誤信息,表明庫存不足時,將回滾該更新。在這種情況下,在插入之后快速檢查 @@ERROR 比在更新之前驗證庫存數量速度要快得多。
InvCtrl 表有一個 CHECK 約束,如果 QtyInStk 列低于 0,就會觸發 547 號錯誤。OrderStock 過程創建一個保存點。如果出現 547 錯誤,它將回滾到該保存點,并將當前手邊有的項目數返回給調用進程。然后調用進程可以決定是否需要針對手邊現有的數量重新下訂單。如果 OrderStock 返回一個 0,則調用進程知道當前有足夠的存貨,可以滿足訂購需要。
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
BEGIN TRANSACTION StkStock
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)
COMMIT TRANSACTION
END
ELSE
COMMIT TRANSACTION
RETURN 0
GO
insert InvCtrl(WhrhousID,PartNmbr,QtyInStk)values(1,1,2)
update InvCtrl set QtyInStk=2 where WhrhousID=1
exec OrderStock 1,1,1
新聞熱點
疑難解答