存儲過程需在同一事務中操作多個數據庫實例的表(如 AccountCapital、logininfo 在默認實例,[Trade]..[order] 在另一實例)。普通事務無法跨實例,需使用分布式事務。
CREATE PROCEDURE deleteAccountAll
@id INT
AS
SET XACT_ABORT ON -- 關鍵:遇錯自動回滾整個分布式事務
BEGIN DISTRIBUTED TRAN -- 開啟分布式事務
DELETE FROM AccountCapital WHERE accountid = @id
DELETE FROM logininfo WHERE username = @id
DELETE FROM CapitalRecord WHERE accountid = @id
DELETE FROM [Trade]..[order] WHERE accountid = @id -- 跨實例:[實例名]..[表名]
DELETE FROM account WHERE id = @id
IF @@ERROR <> 0
ROLLBACK TRAN
ELSE
COMMIT TRAN
GO
services.msc → Distributed Transaction Coordinator → 啟動類型設為「自動」並啟動。net start msdtc。[LinkedServerName].[DatabaseName].[SchemaName].[TableName]
-- 或直接用實例名(若已配置鏈接服務器)
[InstanceName]..[TableName] -- Schema 省略默認 dbo
| 現象 | 原因 | 解決 |
|---|---|---|
| 「MSDTC 在服務器上不可用」 | 服務未啟動或防火牆阻擋 | 啟動服務、開放端口、檢查「網絡 DTC 訪問」權限 |
| 分布式事務升級失敗 | 連接池導致連接復用,事務提升衝突 | 連接字符串加 Enlist=false 或手動 SqlConnection.EnlistDistributedTransaction |
| 跨實例查詢報「找不到服務器」 | 鏈接服務器未建或名稱錯誤 | sp_addlinkedserver 正確建立,sp_testlinkedserver 測試 |
SET XACT_ABORT ON 讓編譯時錯誤(如表不存在)也能觸發回滾,否則需手動檢查 @@ERROR。