代码之家  ›  专栏  ›  技术社区  ›  Andrew

MSDTC-与基础事务管理器的通信失败(防火墙打开,MSDTC网络访问打开)

  •  2
  • Andrew  · 技术社区  · 16 年前

    我的ASP.NET web窗体系统有问题。

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

    我们还使用msdtc-ping来测试连接,并在防火墙上修改ping成功,但是同样的错误发生了!

    如何解决此错误?

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

    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);
                }
    

    这是出现问题时得到的错误堆栈:

    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)
    
    4 回复  |  直到 16 年前
        1
  •  2
  •   Andrew    16 年前

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

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

    This article helped me resolve it

        2
  •  1
  •   Kiran Mali    10 年前

    就我而言,我是通过VPN来尝试的。它在局域网中工作得非常好,但在VPN中却不行。我还打开了两个站点的硬件防火墙中的端口(即1355000-5020),但都被入侵了。在对它搜索了很多之后,我才知道这两台机器应该都能和它们的机器通信 NetBIOS名称 . 我刚刚在hosts文件中添加了另一个machin的条目;现在天气非常好。

    非常感谢。

        3
  •  0
  •   Ivan    16 年前

    我知道你可以打开端口和配置MSDTC,但不是所有安装你的应用程序的客户端。是否有方法阻止TransactionScope升级到DTC。 我知道我只和一个DB一起工作。我只需要多个上下文,以便处理在错误中或错误发生后所做更改的上下文。当然,最好的方法是从数据上下文中分离对象,但在.NET3.5SP1LINQtoSQL中没有此功能。 所以我必须在不同的环境下提交更改,如果出了问题就扔掉。

        4
  •  0
  •   Mike McPhail    10 年前

    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
    
    推荐文章