此異常通常發生在嘗試重複使用已提交或已回滾的 SqlTransaction 物件時。正確做法是每個業務邏輯單元建立獨立事務,並在 try-catch-finally 區塊中確保妥善釋放。
using (SqlConnection conn = new SqlConnection(connectionString))
{
conn.Open();
using (SqlTransaction trans = conn.BeginTransaction(IsolationLevel.ReadCommitted))
{
try
{
// 此處執行多條 SQL,共用同一事務
ExecuteNonQuery(trans, "INSERT INTO StuInfo ...", parameters);
ExecuteNonQuery(trans, "INSERT INTO StuSkill ...", parameters);
trans.Commit();
Console.WriteLine("資料寫入成功");
}
catch (Exception ex)
{
try { trans.Rollback(); } catch { /* 忽略回滾異常 */ }
// 記錄錯誤、拋出或處理
throw;
}
} // 自動 Dispose,釋放連線
}
Commit() 或 Rollback() 後,該 SqlTransaction 實例即失效,切勿再次呼叫。SqlConnection、SqlTransaction、SqlCommand 正確釋放非受控資源。ReadCommitted 為預設且多數場景適用;高併發需考慮 Snapshot 或鎖提示。' 錯誤:嘗試重用事務
trans.Commit();
trans.Commit(); ' 拋出「SqlTransaction 已完成」
' 錯誤:Catch 區塊未 Rollback 導致連線泄漏
catch (Exception ex) {
// 忘記 Rollback,連線池中殘留未完成事務
}
using (var scope = new TransactionScope())
{
using (var conn = new SqlConnection(connStr))
{
conn.Open();
// 多條操作自動登記至環境事務
ExecuteNonQuery(conn, "INSERT ...", params);
ExecuteNonQuery(conn, "UPDATE ...", params);
}
scope.Complete(); // 無例外時提交
}
TransactionScope 支援分散式事務、自動管理連線登記,程式碼更簡潔安全。