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

时间:2010-03-23 08:13:43

标签: asp.net transactionscope mstdc

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

它在我们的测试服务器上工作但是现在我们正在将其置于其中一个服务器位于DMZ内,而SQL服务器位于其外部(尽管我们的网络仍然是一个不同的子网)

我已经在这两个框之间完全打开防火墙以查看是否存在问题,并且每当我们尝试使用“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);
            }

这是我们在出现问题时得到的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)

4 个答案:

答案 0 :(得分:2)

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

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

This article helped me resolve it

答案 1 :(得分:1)

就我而言,我是通过VPN尝试的。它在局域网中工作得非常好,但在VPN中却没有。我还在两个站点的硬件防火墙中打开了端口(即135,5000-5020),但仍然可以使用。在搜索了很多之后,我才知道机器应该可以与他们的 NetBIOS NAME进行通信。我刚刚在主机文件中添加了另一个机器的条目&amp;它现在完全没法了。

感谢Andrew&amp;迈克提供了宝贵的帮助。

谢谢。

答案 2 :(得分:0)

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

答案 3 :(得分:0)

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

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