2015-04-02 3 views
32

Я получаю эту странную ошибку на SQL Server. И я не могу найти решение в более старых сообщениях.MSDTC на сервере server недоступен

У меня есть эта процедура:

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

+0

ну, это похоже на то, что подключенный сервер [LOCAL_MYSQL] запущен, но это может произойти, что недостижимо. В этом случае, если sp_executesql возвращает ошибку, я делаю что-то еще. Обратите внимание, что _upJM_SyncAll_test - это просто процедура тестирования для этого сообщения, _upJM_SyncAll более сложна. – Kiki

ответ

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

+0

Спасибо за ссылку на технологию. Я следовал инструкциям в нем и решил свою проблему. – Rich

88

В моем случае, служба была остановлена ​​. Решение: необходимо включить службу MSDTC на

  1. пойти Услуги. (Пуск> Настройка> Панель управления> Администрирование> Службы)
  2. Найти услугу под названием «Координатор распределенных транзакций» и правой кнопкой мыши (на нем и выберите)>Start.
  3. сделать эту услугу для запуска Автоматически для решения этой проблемы постоянно службы
+7

Кроме того, может оказаться полезным сделать автоматический запуск службы. Щелкните правой кнопкой мыши службу -> Свойства -> Тип запуска и выберите «Автоматически».В противном случае вам нужно будет делать это каждый раз, когда ваш компьютер перезагружается (или если служба останавливается по какой-либо причине) – Rob

+0

Спасибо. работал на меня тоже. –

0

«Координатор распределенных транзакций» не работает, поэтому начал обслуживание и измененный тип сервиса для автоматического тоже.

Смежные вопросы