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

MSSQL 事務中「無法在手動/分散式事務下建立新連接」錯誤根因與解決:游標模式衝突

     編輯:關於SqlServer

經典 ADO 錯誤:「Cannot start transaction while in firehose mode」或「Cannot create new connection in manual/distributed transaction mode」。根因:Firehose 唯讀前向游標 與 交易/批次模式 互斥。本文透過 MSDN 文檔分析三種錯誤場景,給出解決方案:改用 Recordset.Open 替代 Connection.Execute。

三大錯誤場景 (MSDN)

場景 1:交易啟動後設定 Command.ActiveConnection 為 Firehose 連線

conn.BeginTrans
rs.Open "SELECT * FROM Msg", conn  -- Firehose 唯讀前向
cmd.ActiveConnection = conn  -- 錯誤:同一連線無法同時參與批次與 Firehose

錯誤:Unspecified error (ODBC) / 僅見於 Err 物件。

場景 2:Firehose 連線上直接啟動交易

rs.Open "SELECT * FROM Msg", conn  -- 連線進入 Firehose 模式
conn.BeginTrans  -- 錯誤:Firehose 模式不可進入交易模式

錯誤:Cannot start transaction while in firehose mode (ODBC/SQL Server)。

場景 3:Firehose 連線上設定 Command 後啟動交易

rs.Open "SELECT * FROM Msg", conn
cmd.ActiveConnection = conn
conn.BeginTrans  -- 錯誤:連線同時參與 Firehose 與批次

錯誤:Cannot start transaction because more than one hdbc is in use (ODBC/SQL Server)。

解決方案:統一使用 Recordset.Open 並正確設定游標屬性

-- 正確模式:明確指定游標類型與鎖類型,避免隱式 Firehose
rs.CursorLocation = adUseClient          -- 客戶端游標 (斷開連線)
rs.Open "SELECT * FROM Msg", conn, adOpenStatic, adLockBatchOptimistic
conn.BeginTrans
-- 後續操作...
conn.CommitTrans
  • adUseClient 將資料取回本地,連線釋放,後續可自由啟動交易。
  • 或 adOpenKeyset / adLockOptimistic (伺服器端游標) 但需確保連線未進入 Firehose。
  • 避免 Connection.Execute 返回隱式 Firehose Recordset。

核心原則

  1. 交易邊界內不要執行會觸發 Firehose 的純查詢 (Connection.Execute、Recordset.Open 無游標參數)。
  2. 先開游標取數 (客戶端游標),再開交易做更新;或用 Command.Execute 直接執行更新 SQL。
  3. 連線字串加 MultipleActiveResultSets=True (MARS, SQL 2005+) 可緩解但非根治。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved