2

我的 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)
4

4 回答 4

2

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

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

这篇文章帮我解决了

于 2010-06-18T12:50:35.390 回答
1

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

感谢 Andrew 和 Mike 的宝贵帮助。

谢谢你。

于 2016-06-28T07:54:52.537 回答
0

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

于 2010-08-14T01:17:37.420 回答
0

这是一些 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
于 2016-04-08T18:09:03.183 回答