首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C# 資料庫交易實務(四):交易回滾機制與原子性保障

     編輯:關於C語言

交易四大特性 (ACID) 之原子性

原子性要求交易內所有操作要麼全做,要麼全不做。若中途發生錯誤,必須執行回滾抹除已執行效果,維護資料庫一致性。

回滾最佳實踐:結合 try-catch


try {
    // 1. 開啟連線、啟動交易
    // 2. 執行多條 DML
    // 3. 人為製造錯誤:CREATE DATABASE 測試回滾
    // 4. 提交交易
    tran.Commit();
} catch (Exception ex) {
    tran.Rollback(); // 完整回滾
    Console.WriteLine("交易錯誤,已回滾:" + ex.Message);
}

完整範例:人為製造錯誤驗證回滾


using System;
using System.Data;
using System.Data.SqlClient;

namespace ASPcn {
    public class DbTran {
        public void DoTran() {
            using (SqlConnection conn = GetConn()) {
                conn.Open();
                SqlCommand cmd = conn.CreateCommand();
                SqlTransaction tran = conn.BeginTransaction();
                cmd.Transaction = tran;

                try {
                    cmd.CommandText = "USE pubs";
                    cmd.ExecuteNonQuery();

                    // 正常更新
                    cmd.CommandText = "UPDATE roysched SET royalty = royalty * 1.10 WHERE title_id LIKE 'PC%'";
                    cmd.ExecuteNonQuery();

                    // 人為製造錯誤:在交易中建立資料庫(需權限,且會導致交易中止)
                    cmd.CommandText = "CREATE DATABASE testdb";
                    cmd.ExecuteNonQuery();

                    // 後續更新不會執行
                    cmd.CommandText = "UPDATE roysched SET royalty = royalty * 1.20 WHERE title_id LIKE 'PS%'";
                    cmd.ExecuteNonQuery();

                    tran.Commit();
                } catch (Exception ex) {
                    tran.Rollback();
                    Console.WriteLine("交易錯誤,已回滾:" + ex.Message);
                }
            }
        }

        private SqlConnection GetConn() {
            string cs = "Data Source=localhost;Integrated Security=SSPI;User ID=sa;Password=";
            return new SqlConnection(cs);
        }
    }

    public class Test {
        public static void Main() {
            new DbTran().DoTran();
            Console.WriteLine("交易處理完成。");
            Console.ReadLine();
        }
    }
}

驗證結果

  • 第一條 UPDATE (royalty * 1.10) 雖已執行,但因後續 CREATE DATABASE 失敗觸發 Rollback(),資料庫狀態回到交易前,無任何變更。
  • 證明 Rollback() 確實維護了原子性與一致性。

常見錯誤與修正

進階:TransactionScope 自動管理


using (var scope = new TransactionScope()) {
    using (var conn = new SqlConnection(cs)) {
        conn.Open();
        // 執行命令...
    }
    scope.Complete(); // 無例外自動 Commit,有例外自動 Rollback
}
  • .NET 2.0+ 推薦使用 System.Transactions.TransactionScope,支援分散式交易、巢狀交易、自動回滾。
  • 需參考 System.Transactions.dll。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
錯誤寫法問題修正
catch 區塊未呼叫 Rollback交易懸掛,鎖不釋放,連線池洩漏catch 必須呼叫 Rollback()
using 區塊包裹 SqlConnection 但未在 catch RollbackDispose 時隱式 Rollback,但例外資訊遺失顯式 Rollback 後再拋出或記錄
多 catch 區塊重複 Rollback第二次 Rollback 擲回 InvalidOperationException統一在單一 catch 或 finally 處理