Msg 7391, Level 16, State 2
The operation could not be performed because OLE DB provider "SQLNCLI"
for linked server "SERVER_B" was unable to begin a distributed transaction.
-- SQL 2000
OLE DB provider 'SQLOLEDB' unable to begin distributed transaction.
[OLE/DB Provider returned message: New transaction cannot enlist in the specified transaction coordinator.]
services.msc → Distributed Transaction Coordinator → 啟動類型:自動 → 啟動
兩台伺服器皆需執行。
註冊表:HKEY_LOCAL_MACHINE\Software\Microsoft\Rpc\Internet
Ports = 5000-5020 (自訂範圍)
PortsInternetAvailable = Y
UseInternetPorts = Y
測試:telnet 、PortQry、Advanced Port Scanner。
連結伺服器查詢中不可包含回查發起端伺服器的操作。
錯誤範例:Server A 發起分散式交易 → 查詢 Server B 連結伺服器視圖 → 視圖 JOIN Server A 表格。
解決:重寫查詢邏輯,或在應用層協調單一交易。
SET XACT_ABORT ON
BEGIN DISTRIBUTED TRANSACTION
UPDATE Server_A.DB.dbo.Table SET ...
INSERT Server_B.DB.dbo.Table ...
COMMIT TRANSACTION
強制發生錯誤時整個交易回滾,避免部分認交易導致 DTC 協調失敗。
所有分散式交易必加。
組件服務 → 我的電腦 → 右鍵內容 → MSDTC 標籤 → 安全性設定:
| 選項 | 設定 | 說明 |
|---|---|---|
| 網路 DTC 存取 | ☑ 啟用 | 允許遠端協調 |
| 允許遠端用戶端 | ☑ 啟用 | 客戶端發起交易 |
| 允許遠端管理 | ☑ 啟用 | 遠端管理 DTC |
| 允許輸入 | ☑ 啟用 | 接受遠端交易 |
| 允許輸出 | ☑ 啟用 | 發起遠端交易 |
| 不需要驗證 | ☑ 啟用 | 工作群組環境必選;網域可用「相互驗證」 |
| DTC 登入帳戶 | NT AUTHORITY\NetworkService | 預設帳戶,勿改 |
設定完成需重啟 MSDTC 服務生效。
-- 方式 1:產品名稱 SQL Server
EXEC sp_addlinkedserver @server = 'ServerB', @srvproduct = 'SQL Server'
-- @server 必須為實際伺服器名稱或 IP
-- 方式 2:指定提供者
EXEC sp_addlinkedserver
@server = 'LinkName',
@provider = 'SQLNCLI',
@datasrc = 'ActualServerNameOrIP'
-- @datasrc 為實際目標
核心原則:SQL 引擎用名稱/IP 連線,DTC 也用名稱/IP 連線 → 雙方解析結果必須一致。
建議:統一用 FQDN 或 IP,在 hosts 檔或 DNS 確保雙向解析。
DTCPing.exe:Microsoft 官方 DTC 連線測試工具(雙向)DTCTester.exe:圖形化測試工具netsh firewall show state / Get-NetFirewallRule:檢查防火牆規則| 現象 | 原因 | 解決 |
|---|---|---|
| 單向通、單向不通 | 防火牆非對稱規則 | 雙向開放 135 + 動態埠 |
| 網域環境驗證失敗 | SPN 未註冊、信任關係斷裂 | 檢查 SPN、網域信任、Kerberos 委派 |
| 啟用「不需要驗證」仍失敗 | 登入帳戶非 NetworkService | 改回 NetworkService 重啟 DTC |
| 連結伺服器用 IP、DTC 用名稱 | 名稱解析不一致 | 統一用 IP 或同步 hosts/DNS |