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

SQL Server 2005 MARS (Multiple Active Result Sets) 架構與應用優勢

     編輯:關於SqlServer

簡介

所有 SQL Server 資料存取 API (ODBC、OLE DB、ADO、SqlClient) 均提供連線與要求的抽象。SQL Server 2000 限制單一連線同一時間僅能有一個待處理要求,常以伺服器端游標繞過限制。SQL Server 2005 引入 MARS (Multiple Active Result Sets),解除此限制,允許單一連線同時擁有多個作用中的結果集。

SQL Server 2000 存取模型回顧

  • 連線抽象:SqlConnection / SQL_HANDLE_DBC
  • 要求抽象:SqlCommand / SQL_HANDLE_STMT
  • 要求形式:T-SQL 批次或預存程序呼叫。
  • 結果產生:SELECT/FETCH 產生資料列,以「預設結果集」 (Default Result Set) 流式傳輸至用戶端。
  • 網路緩衝區機制:資料列寫入網路緩衝區,用戶端讀取釋放緩衝區;若用戶端未消費,伺服器執行緒阻塞等待。

「連線忙碌」問題範例

情境:鬆散耦合的清單處理系統,使用 Operations 資料表作為佇列。應用程式需:

  1. 讀取佇列取得作業代碼。
  2. 根據代碼執行對應業務邏輯(可能包含多個 SELECT/UPDATE)。
  3. 完成後標記作業已處理。

在 SQL Server 2000,步驟 1 的讀取游標開啟期間,無法在同一連線上執行步驟 2 的業務邏輯,必須開啟第二個連線或使用伺服器端游標,增加資源消耗與程式複雜度。

MARS 解決方案

  • 單一連線可同時擁有多個 SqlCommand 物件處於執行狀態。
  • 可在讀取 SqlDataReader 期間,於同一連線發出新命令 (INSERT/UPDATE/SELECT)。
  • 消除「連線忙碌」錯誤,簡化連線池管理,減少連線數量。

應用程式設計考量

  • 連接字串啟用:MultipleActiveResultSets=True (預設關閉)。
  • 交易範圍:MARS 下單一交易可跨多個作用中命令,需謹慎管理交易邊界。
  • 資源使用:雖減少連線數,但單一連線上同時多個命令會增加伺服器端記憶體與排程壓力,需監控效能。
  • 相容性:僅支援 SQL Server 2005 及以上版本,SqlClient 2.0+ 提供者。

程式碼範例 (C#)

string connStr = "Server=.;Database=Test;Integrated Security=True;MultipleActiveResultSets=True";
using (SqlConnection conn = new SqlConnection(connStr))
{
    conn.Open();
    SqlCommand cmdQueue = new SqlCommand("SELECT TOP 1 OpId, OpCode FROM Operations WHERE Processed=0", conn);
    SqlDataReader reader = cmdQueue.ExecuteReader();

    while (reader.Read())
    {
        int opId = reader.GetInt32(0);
        string opCode = reader.GetString(1);

        // 同一連線、同一交易內執行業務邏輯
        using (SqlTransaction tx = conn.BeginTransaction())
        {
            try
            {
                SqlCommand cmdBiz = new SqlCommand("EXEC ProcessOperation @OpCode", conn, tx);
                cmdBiz.Parameters.AddWithValue("@OpCode", opCode);
                cmdBiz.ExecuteNonQuery();

                SqlCommand cmdUpdate = new SqlCommand("UPDATE Operations SET Processed=1 WHERE OpId=@Id", conn, tx);
                cmdUpdate.Parameters.AddWithValue("@Id", opId);
                cmdUpdate.ExecuteNonQuery();

                tx.Commit();
            }
            catch
            {
                tx.Rollback();
                throw;
            }
        }
    }
    reader.Close();
}

此範例展示在讀取佇列資料的同時,於同一連線內開啟交易執行業務邏輯與更新狀態,無需額外連線。

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