語言
Multiple Active Result Set (MARS) 是與 SQL Server 搭配使用的功能,允許在單一連線中執行多個批次作業。 在啟用 MARS 與 SQL Server 搭配使用時,使用的每個命令物件都會在連線中新增一個工作階段。
注意
單一 MARS 工作階段會開啟一個邏輯連線以供 MARS 使用,然後針對每個使用中的命令建立一個邏輯連線。
在連接字串中啟用及停用 MARS
注意
以下連線字串使用了 SQL Server 附帶的範例 AdventureWorks 資料庫。 提供的連接字串假設資料庫已安裝於名為 MSSQL1 的伺服器上。 請依據環境需求修改連接字串。
此 MARS 功能預設為停用。 只要將 "MultipleActiveResultSets=True" 關鍵字組新增至連接字串,即可加以啟用。 "True" 是啟用 MARS 的唯一有效值。 下列範例示範如何連線到 SQL Server 的執行個體,以及如何指定應該啟用 MARS。
Dim connectionString As String = "..." & _
"MultipleActiveResultSets=True"
string connectionString = "..." +
"MultipleActiveResultSets=True";
您可以藉由將 "MultipleActiveResultSets=False" 關鍵字組新增至連接字串來停用 MARS。 "False" 是停用 MARS 的唯一有效值。
使用 MARS 時的特殊考量
一般來說,現有的應用程式應該不需要修改,就能使用已啟用 MARS 的連線。 不過,如果您想要在應用程式中使用 MARS 功能,就應該了解下列特殊考量。
語句交錯
MARS 作業會在伺服器上同步執行。 允許 SELECT 與 BULK INSERT 陳述式交錯出現。 但是,資料操作語言 (DML) 和資料定義語言 (DDL) 陳述式會以原子性方式執行。 當原子批次正在執行時,任何嘗試執行的陳述式都會遭到封鎖。 在伺服器上平行執行不是 MARS 功能。
如果在 MARS 連線下提交兩個批次,其中一個包含 SELECT 語句,另一個包含 DML 語句,DML 可以在執行該 SELECT 語句的過程中開始執行。 然而,DML 陳述必須先執行完成,SELECT 陳述式之後才能繼續進行。 如果兩個敘述都在同一個交易下執行,在 SELECT 敘述開始執行之後,DML 敘述所做的任何變更,讀取操作都看不到。
在SELECT陳述句中的WAITFOR陳述句在等待期間,也就是說,直到產生第一列為止,不會讓出該交易。 這表示當 WAITFOR 陳述式正在等待時,無法在同一連線內執行其他批次。
MARS 工作階段快取
當連線在啟用 MARS 的情況下開啟時,提供者會建立邏輯會話,這會增加開銷。 為了降低開銷,每個 SqlClient 連線最多可快取 10 個 MARS 會話。 限制無法由使用者調整。 若達到限制,提供者會建立新的工作階段,不會出現錯誤。 快取及其會話不會跨連線共享。 使用後,會話會回到快取,除非快取已滿,此時提供者會關閉會話。 快取會話不會過期;當你釋放該連線時,供應商會幫你清理。 當應用程式需要會話時,提供者會填充快取。
執行緒安全性
MARS 操作不是執行緒安全。
連接共用
已啟用 MARS 的連線就像任何其他連線一樣都是集區式的。 如果應用程式開啟兩個連線,一個已啟用 MARS,另一個已停用 MARS,則這兩個連線會位於不同的集區。 如需詳細資訊,請參閱 SQL Server 連線共用 (ADO.NET)。
SQL Server 批次執行環境
開啟連線時,即會定義預設的環境。 接著會將此環境複製到邏輯的 MARS 會話中。
批次執行環境包括下列元件:
設定選項(例如,
ANSI_NULLS,DATE_FORMAT,LANGUAGE,TEXTSIZE)資訊安全內容 (使用者/應用程式角色)
資料庫內容 (目前的資料庫)
執行狀態變數(例如
@@ERROR,@@ROWCOUNT,@@FETCH_STATUS@@IDENTITY)最上層暫存資料表
使用 MARS,預設執行環境就會與連線產生關聯。 針對指定連線而開始執行的每一個新批次,都會收到預設環境的複本。 每當在指定批次中執行程式碼時,對環境所做的所有變更範圍都會侷限於該特定批次。 執行完成之後,執行設定就會複製到預設環境中。 如果是在相同交易下發出數個要循序執行之命令的單一批次,則語意會與涉及早期用戶端或伺服器之連線所公開的語意相同。
平行執行
MARS 並非設計來移除應用程式中有多個連線的所有需求。 如果應用程式需要對伺服器進行真正的命令平行執行,就應該使用多個連線。
例如,請設想下列情況。 已建立兩個命令物件,一個用於處理結果集,另一個則用於更新資料;它們會透過 MARS 共用一般連線。 在此案例中,Transaction.
Commit 會無法更新,直到第一個命令物件上的全部結果均讀取完畢,並產生下列例外狀況:
訊息:交易上下文正由另一個會話所使用。
來源: .NET SqlClient 資料提供者
預期:(Null)
收到:Microsoft.Data.SqlClient.SqlException
有三個選項可用來處理此案例:
建立讀取器之後啟動交易,因此它不屬於交易的一部分。 接著,每個更新都會變成它自己的交易。
在讀取器關閉後認可所有工作。 這可能會有大量的批次更新。
不要使用 MARS,而是針對每個命令物件改為使用個別連線,就像您在 MARS 之前所做的一樣。
偵測 MARS 支援
應用程式可以藉由讀取 SqlConnection.ServerVersion 值來檢查 MARS 支援。 SQL Server 2005 的主要版本號碼應為 9,而 SQL Server 2008 的則為 10。