MSDTC - сбой связи с соответствующим менеджером транзакций (брандмауэр открыт, доступ к сети MSDTC включен) - PullRequest
2 голосов
/ 23 марта 2010

У меня проблемы с моей системой веб-форм ASP.NET.

Это сработало на нашем тестовом сервере, но сейчас мы запускаем его, один из серверов находится в демилитаризованной зоне, а SQL-сервер - снаружиоб этом (в нашей сети все еще, хотя - хотя другая подсеть)

Я полностью открыл брандмауэр между этими двумя полями, чтобы увидеть, если это было проблемой, и он все еще выдает сообщение об ошибке «Связь с базовымдиспетчер транзакций терпел неудачу "всякий раз, когда мы пытаемся использовать" TransactionScope ".Мы можем получить доступ к данным для извлечения, это просто транзакции, которые их нарушают.

Мы также использовали msdtc ping для проверки соединения и с поправками на брандмауэре, которые успешно проверяют связь, но возникает та же ошибка!

Как мне разрешить эту ошибку?

Любая помощь будет полезна, потому что у нас есть система, которая будет запущена сегодня.Паника:)

Редактировать: Я создал более простую тестовую страницу с транзакцией, как показано ниже, и это прекрасно работает.Может ли вложенная транзакция вызвать такую ​​ошибку, и если да, то почему это может вызвать проблему только при использовании live box в 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 ]

2 голосов
/ 18 июня 2010

Я понял, что предоставленный мною код не приведет к передаче транзакции в DTC. У меня возникла проблема при использовании нескольких контекстов данных в одной транзакции.

Хотя я думал, что брандмауэр открыт, ему нужен диапазон портов, и поэтому проблема все еще возникала.

Эта статья помогла мне решить эту проблему

1 голос
/ 28 июня 2016

В моем случае я пробовал это через VPN.Он отлично работал в локальной сети, но не в VPN.Я также открыл порты (т. Е. 135,5000-5020) в аппаратном брандмауэре на обоих сайтах, но перестал работать.После долгих поисков я узнал, что ОБА МАШИНЫ ДОЛЖНЫ ИМЕТЬ СВЯЗЬ С ИМИ ИМЯ NetBIOS .Я только что добавил запись о другой машине в файл хостов, и теперь она прекрасно работает.

Спасибо Andrew & Mike за ценную помощь.

Спасибо.

0 голосов
/ 08 апреля 2016

Вот некоторый скрипт powershell, который может внести все изменения, необходимые для правильной работы DTC. Вы должны выполнить это на обеих машинах, которые участвуют в транзакции, то есть на вашем веб-сервере и на сервере 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
0 голосов
/ 14 августа 2010

Я понимаю, что вы можете открывать порты и настраивать MSDTC, но не для всех клиентов, на которых установлено ваше приложение.Есть ли способ заблокировать TransactionScope от продвижения в DTC.Я знаю, что работаю только с одной БД.Мне просто нужно несколько контекстов, чтобы избавиться от контекста с изменениями, сделанными по ошибке или после возникновения ошибки.Конечно, лучший способ - это отсоединить объект от контекста данных, но эта функция недоступна в .NET 3.5SP1 Linq to SQL.Поэтому я должен представить изменения в другом контексте и выбросить их, если что-то пойдет не так.

...