2010-04-12 62 views
36

說我有一個由多個獨立的SELECT,INSERT,UPDATE和DELETE語句組成的存儲過程。沒有明確的BEGIN TRANS/COMMIT TRANS/ROLLBACK TRANS邏輯。SQL Server如何處理存儲過程中與事務相關的語句?

SQL Server如何處理這個存儲過程事務方面?每個陳述會有一個隱含的聯繫嗎?或者是否會有一個存儲過程事務?

另外,我怎麼能使用T-SQL和/或SQL Server Management Studio自己發現這一點?

謝謝!

回答

29

只有一個連接,無論存儲過程中有多少SQL命令,它都是用來運行該過程的。

由於存儲過程中沒有顯式的BEGIN TRANSACTION,因此每個語句都將自行運行,並且無法在任何錯誤時回滾任何更改。但是,如果在調用存儲過程之前發出BEGIN TRANSACTION,則所有語句都歸入事務中,並且可以在存儲過程執行後進行COMMIT或ROLLBACK。

從存儲過程中,您可以通過檢查系統變量@@TRANCOUNT (Transact-SQL)的值來確定您是否在事務中運行。零意味着沒有事務,其他任何事情都會顯示您所處的事務嵌套級別。根據您的SQL Server版本,您也可以使用XACT_STATE (Transact-SQL)

如果你做到以下幾點:在過程中

BEGIN TRANSACTION 

EXEC my_stored_procedure_with_5_statements_inside @Parma1 

COMMIT 

一切由事務覆蓋,所有6個報表(以下EXEC是由交易涉及的聲明中,1 + 5 = 6)。如果你這樣做:

BEGIN TRANSACTION 

EXEC my_stored_procedure_with_5_statements_inside @Parma1 
EXEC my_stored_procedure_with_5_statements_inside @Parma1 

COMMIT 

兩個過程調用內的一切都是由事務覆蓋,所有12個語句(2名高管都聲明成交,1 + 5 + 1 + 5 = 12覆蓋)。

+0

所以,你說實際上,存儲過程中的每個語句都會形成自己的事務,即一個具有五個語句的存儲過程會在五個事務中執行? – Sleepless 2010-04-12 12:59:28

+0

如果程序中沒有事務或外部程序包裝,則程序中的每個語句都是一個獨立的工作單元。沒有真正的交易,因爲你不能提交或回滾。如果您在事務中包裝過程調用,那麼過程中的所有內容都將在該單個事務中執行。 – 2010-04-12 13:04:02

+0

謝謝!順便說一句,你怎麼做代碼格式,我明顯失敗了? – Sleepless 2010-04-12 13:15:32

1

你可以通過創建一個簡單的小存儲過程來找到你自己,例如插入一條記錄到測試表中。然後開始Tran;運行sp_test;回滾;那裏有新紀錄嗎?如果是這樣,那麼SP忽略外部交易。如果不是,那麼SP就是交易內部執行的另一個語句(我很確定是這種情況)。

相關問題