我有一個在TransactionScope中運行的代碼塊,在這段代碼中,我對數據庫進行了幾次調用。選擇,更新,創建和刪除整個色域。當我執行我的刪除時,我使用SqlCommand的擴展方法執行它,如果它死鎖,將自動重新提交查詢,因爲此查詢可能會造成死鎖。TransactionScope過早完成
我相信當遇到死鎖並且函數試圖重新提交查詢時會發生問題。這是我收到的錯誤:
與當前連接關聯的事務已完成但尚未處理。事務必須在連接可用於執行SQL語句之前進行處理。
這是簡單的代碼執行查詢(所有代碼的使用TransactionScope的內下面執行):
using (sqlCommand.Connection = new SqlConnection(ConnectionStrings.App))
{
sqlCommand.Connection.Open();
sqlCommand.ExecuteNonQueryWithDeadlockHandling();
}
這裏是重新提交膠着查詢擴展方法:
public static class SqlCommandExtender
{
private const int DEADLOCK_ERROR = 1205;
private const int MAXIMUM_DEADLOCK_RETRIES = 5;
private const int SLEEP_INCREMENT = 100;
public static void ExecuteNonQueryWithDeadlockHandling(this SqlCommand sqlCommand)
{
int count = 0;
SqlException deadlockException = null;
do
{
if (count > 0) Thread.Sleep(count * SLEEP_INCREMENT);
deadlockException = ExecuteNonQuery(sqlCommand);
count++;
}
while (deadlockException != null && count < MAXIMUM_DEADLOCK_RETRIES);
if (deadlockException != null) throw deadlockException;
}
private static SqlException ExecuteNonQuery(SqlCommand sqlCommand)
{
try
{
sqlCommand.ExecuteNonQuery();
}
catch (SqlException exception)
{
if (exception.Number == DEADLOCK_ERROR) return exception;
throw;
}
return null;
}
}
上線會出現錯誤:
sqlCommand.ExecuteNonQuery();
感謝您的技巧抑制選擇語句上的交易。這有助於解決超時問題,這讓我發瘋。 – 2011-08-16 16:10:24
夢幻般的答案。這讓我瘋狂的選擇/插入集合的SQL指令的集合。添加Suppress選項可自動解決問題。 – IoChaos 2012-02-23 22:31:00
神聖的廢話謝謝你!我一整天都在摔跤。這種簡單的解決方案。 – rossipedia 2012-10-05 03:03:06