【问题标题】:MSDTC on server 'server is unavailable'服务器“服务器不可用”上的 MSDTC
【发布时间】:2015-04-02 13:31:03
【问题描述】:

我在 SQL 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

我收到此错误:

消息 8501,级别 16,状态 3,过程 _upJM_SyncAll_test,第 54 行
服务器“服务器”上的 MSDTC 不可用。

Procedure _upJM_SyncAll_test 只有 39 行...

【问题讨论】:

  • 一开始为什么要使用动态SQL?,好像没必要
  • 嗯,就是这样。链接服务器 [LOCAL_MYSQL] 已启动并正在运行,但可能会发生无法访问的情况。在这种情况下,如果 sp_executesql 返回错误,我会执行其他操作。请注意,_upJM_SyncAll_test 只是本文的测试程序,_upJM_SyncAll 更复杂。

标签: sql-server linked-server msdtc


【解决方案1】:

就我而言,服务已停止。解决方法:需要开启MSDTC服务

  1. 转到服务。 (开始 > 设置 > 控制面板 > 管理工具 > 服务)
  2. 找到名为“Distributed Transaction Coordinator”的服务并 右键单击(然后选择)> 开始。
  3. 让此服务自动运行以永久解决此问题

【讨论】:

  • 另外,使服务自动启动可能很有用。右键单击服务-> 属性-> 启动类型,然后选择“自动”。否则,每次您的机器重新启动(或服务因任何原因停止)时,您都需要执行此操作
  • 这是一个比公认的答案更好、更简单的解决方案
【解决方案2】:

触发器包含在插入、更新和删除语句所需的隐式事务中。因为您要连接到事务中的链接服务器,所以 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" /f /v NetworkDtcAccess /t REG_DWORD /d 1
REG ADD "HKLM\Software\Microsoft\MSDTC\Security" /f /v NetworkDtcAccessTransactions /t REG_DWORD /d 1
REG ADD "HKLM\Software\Microsoft\MSDTC\Security" /f /v NetworkDtcAccessInbound /t REG_DWORD /d 1
REG ADD "HKLM\Software\Microsoft\MSDTC\Security" /f /v NetworkDtcAccessOutbound /t REG_DWORD /d 1
PAUSE

net stop MSDTC
net start MSDTC
PAUSE

【讨论】:

  • 第一次暂停后,您可以在所有命令中添加 /f 选项:“在没有提示的情况下强制覆盖现有的注册表项。”否则这将不起作用。除此之外,这项工作完美无缺,谢谢!
  • 感谢技术网链接。我按照里面的说明解决了我的问题。
  • 一件事是启动MSDTC,但open inbound and outbound transactions是什么意思,为什么需要它?
【解决方案3】:

我遇到了同样的错误,但它不像分布式事务协调器服务没有运行那么简单。我通过 Windows 自动收到驱动程序更新,导致 COM+ 出现问题,并且即使 MSDTC 服务正在运行,也不允许 MSDTC 正常通信。就我而言,这是 HP 热键驱动程序的问题,但在研究中,我发现其他制造商的音频驱动程序问题的其他报告也导致了此问题。

要检查您是否有类似的问题,请启动组件服务 (dcomcnfg.exe),然后展开组件服务 > 计算机 > 我的电脑,从此处单击“COM+ 应用程序”以查看是否会弹出错误“COM+ 无法与 Microsoft 分布式事务处理协调器对话”,否则导航中的“我的电脑”图标上会出现红色错误。

我的解决方法是禁用“HP Hotkey Service”和“HotKeyServiceUWP”服务。一旦这些服务被禁用,MSDTC 立即开始工作。

【讨论】:

  • 伙计,你的解决方案救了我。谢谢一百万!
  • 非常感谢!这导致我寻找联想成为罪魁祸首的可能性。原来是LenovoSmartStandby 服务需要被禁用作为临时解决方法。见this link for more information
  • 天啊!!我遇到完全相同的问题的几率是多少,谢谢一百万!
  • 在我的例子中 - Lenovo ThinkPad P52 - 原因是“杜比 DAX API 服务”。
  • 禁用所有 HP 服务对我有用,错误消失了。 (在 Win 10 上测试)
【解决方案4】:

通过禁用有冲突的服务/驱动程序解决了我的问题。我禁用了所有 HP 服务(HP App Helper、HP CASL、HP System Info),现在它可以正常工作了。

【讨论】:

  • 此处为“HP 打印和扫描医生”
【解决方案5】:

“分布式事务协调器”服务未运行,因此启动服务并将服务类型也更改为自动。

【讨论】:

    【解决方案6】:

    在我的情况下,我在远程服务器上有一个 Microsoft SQL Server 的命名实例,我的应用程序的错误输出如下所示:

    System.Data.SqlClient.SqlException (0x80131904): MSDTC on server 'SERVER\INST_NAME' is unavailable.
    

    尝试使用 SQL 连接字符串,例如将 SERVER\INST_NAME 替换为 SERVER,TCP_PORT_NUMBER 并没有帮助。我仍然遇到同样的错误,我决定安装一个默认实例 (MSSQLSERVER),以便 SQL Server 名称仅变为 SERVER。这解决了 RPC 和 MSDTC 开始解析名称的问题。

    【讨论】:

      【解决方案7】:

      Powershell 解决方案:

      Get-Service -Name MSDTC | Set-Service -StartupType Automatic
      

      【讨论】:

        【解决方案8】:

        最近这在我的工作机器(Win 10、MSSQL 2016 SP2 Express)上出现了问题。我没有链接服务器。这从无到有。 MSDTC 服务正在运行,MSSQL 使用 Mgmt Studio 可以正常工作。但是,我的 .NET 4.7.1 单元测试应用程序拒绝与数据库连接,并出现“服务器'...' 上的 MSDTC 不可用”错误。

        我发现的临时解决方法是添加“Enlist=False;”在连接字符串的末尾,以避免在连接中使用 MSDTC。

        此解决方案的来源是该主题下的评论:https://docs.microsoft.com/en-us/archive/blogs/distributedservices/intermittent-error-msdtc-on-server-servername-is-unavailable

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-03-12
          相关资源
          最近更新 更多