2008-10-07 50 views
32

如果我在SQL中創建存儲過程並在BEGIN/END TRANSACTION中調用它(EXEC spStoredProcedure),那麼這個其他存儲過程是否也屬於事務?在BEGIN/END TRANSACTION中執行存儲過程

我不知道它是否像C#中的try/catches一樣工作。

回答

33

是,所有內容您在開始事務和提交(或回滾)之間執行的事務是事務的一部分。

+5

這並非完全正確。實際上,對錶變量的操作不在事務範圍之內;回滾不會影響您的表變量中所做的任何更改。 – 2009-09-03 15:10:42

+5

嗯,我的意思是你對數據庫做的所有事情* - 我想我很明白變量不受事務影響 - 儘管我認爲它比表變量更不直觀,而不是標量變量。 – Blorgbeard 2009-09-03 22:20:42

5

我相信MS SQL Server中的存儲過程執行會發生在事務中,但要非常小心。如果您有嵌套事務(即,存儲過程之外的事務和存儲過程內的不同事務),回滾將影響所有事務,而不僅僅是最近的封閉事務。

1

是的,所有嵌套的存儲過程調用都包含在事務的範圍內。如果您使用的是SQL Server 2005或更高版本,則也可以使用Try ... Catch。 Here就是這方面的更多細節。

11

聽起來不錯,謝謝一堆。我最終做了這樣的事情(因爲我在05)

BEGIN TRY 
     BEGIN TRANSACTION 

     DO SOMETHING 

     COMMIT 
    END TRY 
    BEGIN CATCH 
     IF @@TRANCOUNT > 0 
     ROLLBACK 

     -- Raise an error with the details of the exception 
     DECLARE @ErrMsg nvarchar(4000), @ErrSeverity int 
     SELECT @ErrMsg = ERROR_MESSAGE(), 
      @ErrSeverity = ERROR_SEVERITY() 

     RAISERROR(@ErrMsg, @ErrSeverity, 1) 
    END CATCH 
5

正如克里斯提到的,你應該小心滾動事務回來。

具體如下:

IF @@TRANCOUNT > 0 ROLLBACK 

並不總是你想要的。你可以做這樣的事情

IF(@@TRANCOUNT = 1) ROLLBACK TRAN 
ELSE IF(@@TRANCOUNT > 1) COMMIT TRAN 
RETURN @error 

這樣,調用PROC可以檢查從存儲過程返回值,並確定它是否想反正提交或繼續泡了錯誤。

原因是'COMMIT'只會減少你的交易計數器。一旦它將事務計數器遞減到零,那麼將發生實際的提交。

1

@Chris,我不知道。

當使用Google搜索獲取更多信息時,我遇到了this - 您可以設置'保存點',該保存點可以回退到無需回滾整個交易。

在這種情況下可能有用。