【问题标题】:MSDTC - Communication with the underlying transaction manager has failed (Firewall open, MSDTC network access on)MSDTC - 与底层事务管理器的通信失败(防火墙打开,MSDTC 网络访问开启)
【发布时间】:2010-03-23 08:13:42
【问题描述】:

我的 ASP.NET Web 表单系统出现问题。

它在我们的测试服务器上运行,但现在我们将其投入使用,其中一台服务器位于 DMZ 内,而 SQL 服务器位于该服务器之外(尽管仍在我们的网络上 - 尽管是不同的子网)

我已经完全打开了这两个框之间的防火墙,看看是否是问题所在,但每当我们尝试使用“TransactionScope”时,它仍然会给出错误消息“与底层事务管理器的通信失败”。我们可以访问数据进行检索,它只是破坏它的事务。

我们也用msdtc ping测试过连接,在防火墙上修改ping成功,还是出现同样的错误!

我该如何解决这个错误?

任何帮助都会很棒,因为我们今天有一个可以上线的系统。恐慌:)

编辑:我创建了一个更简单的测试页面,其中包含如下事务,并且效果很好。嵌套事务会导致这种错误吗?如果会,为什么只会在带防火墙的 dmz 中使用 live box 时才会导致问题?

AuditRepository auditRepository = new AuditRepository();

            try
            {
                using (TransactionScope scope = new TransactionScope())
                {
                    auditRepository.Add(DateTime.Now, 1, "TEST-TRANSACTIONS#1", 1);
                    auditRepository.Save();
                    auditRepository.Add(DateTime.Now, 1, "TEST-TRANSACTIONS#2", 1);
                    auditRepository.Save();

                    scope.Complete();
                }
            }
            catch (Exception ex)
            {
                Response.Write("Test Error For Transaction: " + ex.Message + "<br />" + ex.StackTrace);
            }

这是我们在问题发生时得到的 ErrorStack: 在

System.Transactions.TransactionInterop.GetOletxTransactionFromTransmitterPropigationToken(Byte[]
  propagationToken) at
  System.Transactions.TransactionStatePSPEOperation.PSPEPromote(InternalTransaction tx)
  at System.Transactions.TransactionStateDelegatedBase.EnterState(InternalTransaction tx)
  at System.Transactions.EnlistableStates.Promote(InternalTransaction tx) at
  System.Transactions.Transaction.Promote() at
  System.Transactions.TransactionInterop.ConvertToOletxTransaction(Transaction
  transaction) at System.Transactions.TransactionInterop.GetExportCookie(Transaction
  transaction, Byte[] whereabouts) at
  System.Data.SqlClient.SqlInternalConnection.GetTransactionCookie(Transaction
  transaction, Byte[] whereAbouts) at
  System.Data.SqlClient.SqlInternalConnection.EnlistNonNull(Transaction tx) at
  System.Data.SqlClient.SqlInternalConnection.Enlist(Transaction tx) at
  System.Data.SqlClient.SqlInternalConnectionTds.Activate(Transaction transaction) at
  System.Data.ProviderBase.DbConnectionInternal.ActivateConnection(Transaction
  transaction) at System.Data.ProviderBase.DbConnectionPool.GetConnection(DbConnection
  owningObject) at
  System.Data.ProviderBase.DbConnectionFactory.GetConnection(DbConnection
  owningConnection) at
  System.Data.ProviderBase.DbConnectionClosed.OpenConnection(DbConnection
  outerConnection, DbConnectionFactory connectionFactory) at
  System.Data.SqlClient.SqlConnection.Open() at
  System.Data.Linq.SqlClient.SqlConnectionManager.UseConnection(IConnectionUser user) at
  System.Data.Linq.SqlClient.SqlProvider.get_IsSqlCe() at
  System.Data.Linq.SqlClient.SqlProvider.InitializeProviderMode() at
  System.Data.Linq.SqlClient.SqlProvider.System.Data.Linq.Provider.IProvider.Execute(Expression
  query) at
  System.Data.Linq.ChangeDirector.StandardChangeDirector.DynamicInsert(TrackedObject
  item) at System.Data.Linq.ChangeDirector.StandardChangeDirector.Insert(TrackedObject
  item) at System.Data.Linq.ChangeProcessor.SubmitChanges(ConflictMode failureMode) at
  System.Data.Linq.DataContext.SubmitChanges(ConflictMode failureMode) at
  System.Data.Linq.DataContext.SubmitChanges() at RegBook.classes.DbBase.Save() at
  RegBook.usercontrols.BookingProcess.confirmBookingButton_Click(Object sender, EventArgs e)

【问题讨论】:

  • 两个盒子上的 msdtc 安全设置如何?是否允许入站和出站?
  • 另外,请确保 msdtc 在防火墙例外中。
  • 当前允许远程客户端、入站/出站且不需要身份验证(仅更改了这个)。使用多个数据上下文或数据库连接时似乎是一个问题,因为它升级到 MSDTC。我让我们的技术团队暂时解锁防火墙并打开两台服务器的所有端口,MSDTC ping 工具正常工作,但仍然出现错误。我想哭:)

标签: asp.net transactionscope mstdc


【解决方案1】:

我意识到我提供的代码不会将交易升级到 DTC。在一个事务中使用多个数据上下文时,我遇到了问题。

虽然我认为防火墙是打开的,但它需要一系列端口,这就是问题仍然存在的原因。

This article helped me resolve it

【讨论】:

    【解决方案2】:

    就我而言,我是通过 VPN 尝试的。它在 LAN 中工作得非常好,但在 VPN 中却不行。我还在两个站点的硬件防火墙中打开了端口(即 135,5000-5020),但没有成功。在搜索了很多之后,我知道两台机器都应该能够与他们的 NetBIOS 名称 进行通信。我刚刚在 hosts 文件中添加了另一个机器的条目,现在它工作得非常好。

    感谢 Andrew 和 Mike 提供的宝贵帮助。

    谢谢。

    【讨论】:

      【解决方案3】:

      我了解您可以打开端口并配置 MSDTC,但不适用于安装了您的应用的所有客户端。有没有办法阻止 TransactionScope 升级到 DTC。 我知道我只使用一个数据库。我只需要多个上下文来处理错误或发生错误后更改的上下文。最好的方法当然是从数据上下文中分离对象,但 .NET 3.5SP1 Linq to SQL 中不提供此功能。 所以我必须在不同的上下文中提交更改,如果出现问题就扔掉。

      【讨论】:

        【解决方案4】:

        这里有一些 powershell 脚本,可以进行所有所需的更改以使 DTC 正常工作。您必须在参与事务的两台机器上运行它,即您的 Web 服务器和 sql 服务器机器。

        function Enable-MSDTC
        {
            [CmdletBinding()]
            param()
        
            Write-Host "Updating registry entries for MSDTC"
            $msdtcRegKey = "HKLM:\SOFTWARE\Microsoft\MSDTC\Security" 
        
            Set-ItemProperty  -Path $msdtcRegKey -Name "NetworkDtcAccessTransactions" -Value 1
            Set-ItemProperty -Path $msdtcRegKey -Name "NetworkDtcAccess" -Value 1
            Set-ItemProperty -Path $msdtcRegKey -Name "NetworkDtcAccessOutbound" -Value 1
            Set-ItemProperty -Path $msdtcRegKey -Name "NetworkDtcAccessClients" -Value 1
            Set-ItemProperty -Path $msdtcRegKey -Name "NetworkDtcAccessInbound" -Value 1
            Set-ItemProperty -Path $msdtcRegKey -Name "LuTransactions" -Value 1
        
           #Configure MSDTC to use specific ports
           #see: https://support.microsoft.com/en-us/kb/250367
           $msdtcPortKey = "HKLM:\SOFTWARE\Microsoft\Rpc\Internet"
           New-Item -Path $msdtcPortKey
           New-ItemProperty -Path $msdtcPortKey -Name "Ports" -PropertyType "MultiString" -Value "5000-5200"
           New-ItemProperty -Path $msdtcPortKey -Name "PortsInternetAvailable" -PropertyType "String" -Value "Y"
           New-ItemProperty -Path $msdtcPortKey -Name "UseInternetPorts" -PropertyType "String" -Value "Y"
        
           #open firewall ports 135, 1433, 5000-5100
           #also add MSDTC program exclusion
        
            netsh advfirewall firewall add rule name='MSDTC Endpoint Mapper (In)' localport=135 dir=in action=allow protocol=TCP
            netsh advfirewall firewall add rule name='MSDTC SQL Server (In)' localport=1433 dir=in action=allow protocol=TCP
            netsh advfirewall firewall add rule name='MSDTC Dynamic Ports (In)' localport=5000-5200 dir=in action=allow protocol=TCP
            netsh advfirewall firewall add rule name='MSDTC exe' dir=in action=allow program=$env:windir\system32\msdtc.exe enable=yes
        
            Write-Host "Restarting MSDTC service"
            #restart the MSDTC service
            Restart-Service MSDTC -Force -Confirm:$false
        }
        
        Enable-MSDTC -ErrorAction SilentlyContinue
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-09-27
          • 2010-09-17
          相关资源
          最近更新 更多