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

三層架構下的交易處理實作:BLL 控制 SqlTransaction、DAL 接收 Transaction 參數、SqlHelper 管理連線

     編輯:ASP.NET 基礎

架構分層職責

層級職責關鍵點
BLL (Business Logic Layer)開啟/提交/回滾交易、協調多個 DAL 操作using (SqlTransaction tran = SqlHelper.BeginTransaction())
DAL (Data Access Layer)執行具體 SQL,接收外部傳入的 SqlTransaction方法簽名加 SqlTransaction tran 參數
SqlHelper管理共用 SqlConnection、提供 BeginTransaction/CloseConnection單一連線實例贯穿交易週期

SqlHelper 核心實作

public static class SqlHelper
{
    private static readonly string ConnStr = ConfigurationManager.ConnectionStrings["Default"].ConnectionString;
    private static SqlConnection _conn = new SqlConnection(ConnStr);

    private static SqlConnection GetConnection()
    {
        if (_conn.State == ConnectionState.Closed) _conn.Open();
        return _conn;
    }

    public static SqlTransaction BeginTransaction()
    {
        return GetConnection().BeginTransaction();
    }

    public static void CloseConnection()
    {
        if (_conn.State != ConnectionState.Closed) _conn.Close();
    }

    // 多載 ExecuteNonQuery 接收 transaction
    public static int ExecuteNonQuery(string sql, SqlParameter[] parameters, CommandType type, SqlTransaction tran)
    {
        using (SqlCommand cmd = new SqlCommand(sql, (SqlConnection)tran.Connection, tran))
        {
            cmd.CommandType = type;
            if (parameters != null) cmd.Parameters.AddRange(parameters);
            return cmd.ExecuteNonQuery();
        }
    }
}

DAL 實作

public class UserDAO
{
    public bool InsertTest(int value, SqlTransaction tran)
    {
        string sql = "INSERT INTO [TestTable]([Item]) VALUES(@val)";
        SqlParameter[] paras = { new SqlParameter("@val", value) };
        return SqlHelper.ExecuteNonQuery(sql, paras, CommandType.Text, tran) > 0;
    }
}

BLL 交易控制流程

public class UserService
{
    private readonly UserDAO _dao = new UserDAO();

    public bool BatchInsert()
    {
        using (SqlTransaction tran = SqlHelper.BeginTransaction())
        {
            try
            {
                _dao.InsertTest(2, tran);
                _dao.InsertTest(3, tran);
                // 可繼續呼叫其他 DAL 方法,共用同一 tran

                tran.Commit();
                return true;
            }
            catch (Exception ex)
            {
                tran.Rollback();
                // 記錄 Log
                return false;
            }
            finally
            {
                SqlHelper.CloseConnection(); // 歸還連線
            }
        }
    }
}

關鍵設計細節解析

  1. 共用連線:SqlHelper._conn 為 static 單例,交易期間保持開啟,所有命令共用此連線。
  2. Transaction 傳遞:BLL 建立 SqlTransaction,透過參數傳給 DAL,DAL 建立 SqlCommand 時指定 cmd.Transaction = tran。
  3. 例外處理:任何 DAL 操作拋出例外,BLL catch 區塊呼叫 tran.Rollback(),確保原子性。
  4. 資源釋放:finally 呼叫 SqlHelper.CloseConnection(),避免連線洩漏。
  5. Thread Safety 警示:Static SqlConnection 非執行緒安全,僅適用單執行緒請求模型(傳統 WebForms 同步請求)。高併發或非同步環境必須改用 using (var conn = new SqlConnection(...)) 每請求一連線。

進階改進:Dependency Injection 與 Unit of Work

// 介面
public interface IUnitOfWork : IDisposable
{
    SqlTransaction BeginTransaction();
    void Commit();
    void Rollback();
}

// 實作(每請求一實例,由 DI 容器管理生命週期)
public class AdoUnitOfWork : IUnitOfWork
{
    private readonly SqlConnection _conn;
    private SqlTransaction _tran;

    public AdoUnitOfWork(string connStr) { _conn = new SqlConnection(connStr); _conn.Open(); }

    public SqlTransaction BeginTransaction() => _tran = _conn.BeginTransaction();
    public void Commit() => _tran?.Commit();
    public void Rollback() => _tran?.Rollback();
    public void Dispose() { _tran?.Dispose(); _conn?.Dispose(); }
}

// BLL 使用
public class UserService
{
    private readonly UserDAO _dao;
    private readonly IUnitOfWork _uow;

    public UserService(UserDAO dao, IUnitOfWork uow) { _dao = dao; _uow = uow; }

    public bool BatchInsert()
    {
        var tran = _uow.BeginTransaction();
        try {
            _dao.InsertTest(2, tran);
            _dao.InsertTest(3, tran);
            _uow.Commit(); return true;
        } catch { _uow.Rollback(); return false; }
    }
}

優點:可測試、執行緒安全、支援非同步、解耦具體 ADO.NET 實作。

總結

傳統三層架構中,BLL 掌控交易邊界、DAL 專注 SQL 執行、SqlHelper 提供共用連線 是經典模式。現代開發建議導入 Unit of Work + DI,獲得更好的可維護性與擴展性。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved