[英]Detecting rollback in SQL Server
當涉及兩個或多個語句時嘗試檢測回滾條件。 對於SqlCommand.ExecuteNonQuery
方法, 文檔說
如果未檢測到有助於計數的語句,則返回值為 -1。 如果發生回滾,則返回值也是 -1。
我故意插入-1
作為具有引用完整性約束的引用表中的無效條目。
string sql = $@"
BEGIN TRANSACTION
BEGIN TRY
DELETE FROM CustomerContact WHERE CustomerId = @Id
INSERT INTO CustomerContact(CustomerId, ContactId) VALUES (3, -1)
COMMIT TRANSACTION
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION
END CATCH";
using (SqlCommand command = new SqlCommand(sql, connection))
{
command.Connection.Open();
command.Parameters.Add("Id", SqlDbType.Int).Value = id;
int result = command.ExecuteNonQuery();
Console.WriteLine(result); // -> returns affected deleted rows but not -1
}
回滾按預期工作,但我沒有從ExecuteNonQuery
獲得-1
,相反,我從DELETE
操作(第一條語句)中獲得了許多受影響的行
我之前確實使用過SqlTransaction
,但我正在測試基於嵌入式 SQL 的事務的行為。
我建議您只輸入CATCH
塊以指示錯誤並發生相應的回滾,而不是嘗試檢測ROLLBACK
本身。
最好指定SET XACT_ABORT ON;
使用 T-SQL 事務確保事務在超時的情況下立即回滾。 這是因為超時發生在客戶端,其中 API 取消正在運行的查詢並阻止帶有ROLLBACK
的 CATCH 塊執行。 然后,連接將通過打開的事務返回到池中,並且鎖尚未釋放。 盡管當池連接被重用/重置或關閉時事務最終會回滾,但 XACT_ABORT 設置將導致立即發生並釋放資源鎖。
下面是我在大多數情況下推薦的 T-SQL 事務管理和結構化錯誤處理模式。 另外,請注意自由使用分號以避免意外。
string sql = $@"
SET XACT_ABORT ON;
BEGIN TRY
BEGIN TRANSACTION;
DELETE FROM CustomerContact WHERE CustomerId = @Id;
INSERT INTO CustomerContact(CustomerId, ContactId) VALUES (3, -1);
COMMIT TRANSACTION;
END TRY
BEGIN CATCH
IF @@TRANCOUNT > 0 ROLLBACK TRANSACTION;
THROW;
END CATCH";
try
{
using (SqlCommand command = new SqlCommand(sql, connection))
{
command.Connection.Open();
command.Parameters.Add("Id", SqlDbType.Int).Value = id;
int result = command.ExecuteNonQuery();
Console.WriteLine(result); // -> returns affected deleted rows but not -1
}
}
catch
{
Console.WriteLine('handle exception here');
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.