2015-04-02 33 views
32

我在SQL Server上出現這個奇怪的錯誤。而且我在舊帖子中找不到解決方案。服務器服務器上的MSDTC不可用

我有這樣的過程:

create proc _upJM_SyncAll_test 
as 
begin 
    DECLARE @SQLString nvarchar(max) 

set @SQLString = N' 
DELETE FROM OPENQUERY([LOCAL_MYSQL],''SELECT acSubject FROM _utjm_setitemprices'') where acSubject not in (select acSubject from _uvJM_SetSubj) 
DELETE FROM OPENQUERY([LOCAL_MYSQL],''SELECT acSubject FROM _utjm_setsubj'') where acSubject not in (select acSubject from _uvJM_SetSubj) 

update a 
set acName2 = b.acName2, 
    acName3 = b.acName3, 
    acAddress = b.acAddress, 
    acPost = b.acPost, 
    acPostName = b.acPostName, 
    acCountry = b.acCountry, 
    acVATCodePrefix = b.acVATCodePrefix, 
    acCode = b.acCode, 
    anDaysForPayment = b.anDaysForPayment 
from OPENQUERY([LOCAL_MYSQL],''SELECT * FROM _utjm_setsubj'') a join _uvJM_SetSubj b on (a.acSubject = b.acSubject) 
where 1=1 
and ( isnull(a.acName2,'''') <> isnull(b.acName2,'''') OR 
     isnull(a.acName3,'''') <> isnull(b.acName3,'''') OR 
     isnull(a.acAddress,'''') <> isnull(b.acAddress,'''') OR 
     isnull(a.acPost,'''') <> isnull(b.acPost,'''') OR 
     isnull(a.acPostName,'''') <> isnull(b.acPostName,'''') OR 
     isnull(a.acCountry,'''') <> isnull(b.acCountry,'''') OR 
     isnull(a.acVATCodePrefix,'''') <> isnull(b.acVATCodePrefix,'''') OR 
     isnull(a.acCode,'''') <> isnull(b.acCode,'''') OR 
     isnull(a.anDaysForPayment,'''') <> isnull(b.anDaysForPayment,'''') 
) 

insert into OPENQUERY([LOCAL_MYSQL],''SELECT * FROM _utjm_setsubj'') (acSubject, acName2, acName3, acAddress, acPost, acPostName, acCountry, acVATCodePrefix, acCode, anDaysForPayment) 
select b.acSubject, b.acName2, b.acName3, b.acAddress, b.acPost, b.acPostName, b.acCountry, b.acVATCodePrefix, b.acCode, b.anDaysForPayment 
from OPENQUERY([LOCAL_MYSQL],''SELECT * FROM _utjm_setsubj'') a right join _uvJM_SetSubj b on (a.acSubject = b.acSubject) 
where a.acSubject is null ' 

EXECUTE sp_executesql @SQLString; 
end 

當我像這樣運行管理工作室程序:

exec dbo._upJM_SyncAll_test 

一切正常。我沒有錯誤,同步工作正常。

但是當我把執行中觸發這樣的:

create trigger _utrJM_SetSubj on tHE_SetSubj after insert, update, delete 
as 
begin 
    exec dbo._upJM_SyncAll_test 
end 

我得到這個錯誤:

Msg 8501, Level 16, State 3, Procedure _upJM_SyncAll_test, Line 54
MSDTC on server 'server' is unavailable.

程序_upJM_SyncAll_test只有39行...

+0

爲什麼你首先使用動態SQL ?,看起來好像沒有必要 – Lamak 2015-04-02 13:32:55

+0

好像這樣..鏈接服務器[LOCAL_MYSQL]啓動並運行,但它可能會發生,無法訪問。在這種情況下,如果sp_executesql返回錯誤我做了別的..請注意,_upJM_SyncAll_test只是測試過程中的這篇文章,_upJM_SyncAll更復雜。 – Kiki 2015-04-02 13:43:34

回答

17

觸發器都包括在插入,更新和刪除語句所需的隱式事務。由於您正在連接到事務內的鏈接服務器,因此SQL Server將它提升爲分佈式事務。

您需要配置MSDTC,您可以打開MMC並加載MSDTC插件,也可以使用以下腳本打開入站和出站事務。

https://technet.microsoft.com/en-us/library/cc731495.aspx

REG QUERY "HKLM\Software\Microsoft\MSDTC\Security" /v NetworkDtcAccess 
REG QUERY "HKLM\Software\Microsoft\MSDTC\Security" /v NetworkDtcAccessTransactions 
REG QUERY "HKLM\Software\Microsoft\MSDTC\Security" /v NetworkDtcAccessInbound 
REG QUERY "HKLM\Software\Microsoft\MSDTC\Security" /v NetworkDtcAccessOutbound 
PAUSE 

REG ADD "HKLM\Software\Microsoft\MSDTC\Security" /v NetworkDtcAccess /t REG_DWORD /d 1 
REG ADD "HKLM\Software\Microsoft\MSDTC\Security" /v NetworkDtcAccessTransactions /t REG_DWORD /d 1 
REG ADD "HKLM\Software\Microsoft\MSDTC\Security" /v NetworkDtcAccessInbound /t REG_DWORD /d 1 
REG ADD "HKLM\Software\Microsoft\MSDTC\Security" /v NetworkDtcAccessOutbound /t REG_DWORD /d 1 
PAUSE 

net stop MSDTC 
net start MSDTC 
PAUSE 
+1

第一次暫停後,可以將/ f選項添加到所有命令:「強制覆蓋現有註冊表項而不提示。」否則這將無法正常工作。除此之外,這個工作完美,謝謝! – codea 2015-12-02 13:17:16

+0

感謝您的technet鏈接。我按照其中的說明解決了我的問題。 – Rich 2017-07-10 18:37:23

88

在我的情況下,服務被停止。解決方法:需要打開MSDTC服務

  1. 轉到服務。 (開始>設置 - >控制面板 - >管理工具>服務)
  2. 查找(它並選擇)被稱爲「分佈式事務處理協調」和 右鍵單擊服務>開始
  3. 使這個服務過解決這個問題的永久
+7

此外,自動啓動服務可能很有用。右鍵單擊服務 - >屬性 - >啓動類型並選擇'自動'。否則,每次重新啓動計算機時都需要執行此操作(或者因爲任何原因停止服務) – Rob 2016-09-22 04:45:40

+0

謝謝。也爲我工作。 – 2017-12-21 10:48:34

0

「分佈式事務處理協調器」服務沒有運行,所以啓動的服務和改變服務類型設置爲自動運行自動