Диспетчер транзакций отключил поддержку удаленных / сетевых транзакций


86

Я использую SQL Server и ASP.NET. У меня есть такая функция:

Using js = daoFactory.CreateJoinScope()
    Using tran = New Transactions.TransactionScope()
        '...
        tran.Complete()
    End Using
End Using

Однако исключение: «Диспетчер транзакций отключил поддержку удаленных / сетевых транзакций. 'брошено.

Описание JoinScope:

Public Class JoinScope
    Implements IJoinScope
    Implements IDisposable
    '...
End Class

Я работал таким образом в другом приложении с той же средой без проблем, но здесь у меня есть эта проблема. Что я мог сделать, чтобы исправить проблему?


Я выполнил шаги, которые сначала предложил Магнус, чтобы убедиться, что у меня, так сказать, охвачены все базы, а затем мне удалось получить ошибку, предполагающую, что я включил clr в SQL Server, и это сработало для меня. msdn.microsoft.com/en-us/library/ms131048.aspx
Ли,

Ответы:


141

Убедитесь, что служба «Координатор распределенных транзакций» работает как в базе данных, так и на клиенте. Также убедитесь, что вы отметили «Доступ к сети DTC», «Разрешить удаленный клиент», «Разрешить входящий / исходящий» и «Включить TIP».

Включение доступа к сети DTC для транзакций MS DTC

  1. Откройте оснастку «Службы компонентов».

    Чтобы открыть Службы компонентов, нажмите Пуск. В поле поиска введите dcomcnfg и нажмите клавишу ВВОД.

  2. Разверните дерево консоли, чтобы найти DTC (например, Local DTC), для которого вы хотите включить сетевой доступ к MS DTC.

  3. В меню «Действие» выберите «Свойства».

  4. Перейдите на вкладку «Безопасность» и внесите следующие изменения: В «Параметры безопасности» установите флажок «Доступ к сети DTC».

    В Transaction Manager Communication установите флажки Allow Inbound и Allow Outbound.


3
Спасибо, Магнус. Это должна быть настройка приложения, потому что этот тип транзакции работал с одними и теми же компьютерами, а это означает, что эта проблема не связана с машиной.
Лайош Арпад,

Да. Это вызывает то же исключение.
Лайош Арпад,

Я думаю, это связано с тем, что вы на самом деле делаете внутри TransactionScope.
Магнус

Кроме того, мне нужна область соединения, потому что я хочу, чтобы эта транзакция отправлялась как один запрос на сервер базы данных.
Лайош Арпад,

13
убедитесь, что вы используете одно и то же открытое соединение для всех вызовов базы данных внутри транзакции.
Магнус

11

У меня периодически возникала эта проблема, я следовал инструкциям здесь и очень похожим инструкциям в других местах. Все было настроено правильно.

Эта страница: http://sysadminwebsite.wordpress.com/2012/05/29/9/ помогла мне найти проблему.

В основном у меня были дублированные CID для MSDTC на обоих серверах. HKEY_CLASSES_ROOT \ CID

См .: http://msdn.microsoft.com/en-us/library/aa561924.aspx раздел Убедитесь, что MSDTC присвоено уникальное значение CID

Я работаю с виртуальными серверами, и наша серверная команда любит использовать один и тот же образ для каждого сервера. Это простое решение, и нам не потребовался перезапуск. Но для службы DTC действительно нужно было установить автоматический запуск и запускать ее после переустановки.


9

У меня была процедура хранилища, которая вызывает другую процедуру хранилища на «связанном сервере». Когда я выполняю ее в ssms, все в порядке, но когда я вызываю ее в приложении (By Entity Framework), я получил эту ошибку. Эта статья мне помогла, и я использовал этот скрипт:

EXEC sp_serveroption @server = 'LinkedServer IP or Name',@optname = 'remote proc transaction promotion', @optvalue = 'false' ;

для более подробной информации посмотрите на это: Связанный сервер: менеджер транзакций партнера отключил поддержку удаленных / сетевых транзакций.


1
Ссылка на решение приветствуется, но убедитесь, что ваш ответ полезен и без нее: добавьте контекст вокруг ссылки, чтобы ваши друзья-пользователи имели некоторое представление, что это такое и почему оно есть, а затем процитируйте наиболее релевантную часть страницы, которую вы повторная ссылка на, если целевая страница недоступна. Ответы, которые представляют собой не более чем ссылку, могут быть удалены.
Петтер Фриберг

1
Это решило мою проблему, поэтому спасибо за это. Я не знаю, почему он получил -1 голос, поскольку он помог исправить мою конкретную проблему.
Boyd P

6

В моем сценарии исключение было выброшено, потому что я пытался создать новый экземпляр соединения в TransactionScope для уже существующего соединения:

Пример:

void someFunction()
{
    using (var db = new DBContext(GetConnectionString()))
    {
        using (var transaction = new TransactionScope(TransactionScopeOption.Required, new TransactionOptions { IsolationLevel = System.Transactions.IsolationLevel.ReadUncommitted }))
        {
            someOtherFunction(); // This function opens a new connection within this transaction, causing the exception.
        }
    }
}

void someOtherFunction()
{
    using (var db = new DBContext(GetConnectionString()))
    {
        db.Whatever // <- Exception.
    }
}

3

Комментарий к ответу : «убедитесь, что вы используете одно и то же открытое соединение для всех вызовов базы данных внутри транзакции. - Магнус»

Наши пользователи хранятся в отдельной базе данных от данных, с которыми я работал в транзакциях. Открытие соединения db для получения пользователя вызывало эту ошибку для меня. Перемещение другого соединения с базой данных и поиска пользователя за пределы области транзакции исправило ошибку.


1

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

Операция не может быть выполнена, потому что поставщик OLE DB _ для связанного сервера _ не смог начать распределенную транзакцию

Менеджер партнерских транзакций отключил поддержку удаленных / сетевых транзакций *

Переход к SQL Client устранил мою проблему, что также подтвердило для меня, что это была проблема EF.

Попытка на основе метода, созданного моделью EF:

db.SomeStoredProcedure();

Попытка на основе ExecuteSqlCommand:

db.Database.ExecuteSqlCommand("exec [SomeDB].[dbo].[SomeStoredProcedure]");

С участием:

var connectionString = db.Database.Connection.ConnectionString;
var connection = new System.Data.SqlClient.SqlConnection(connectionString);    
var cmd = connection.CreateCommand();
cmd.CommandText = "exec [SomeDB].[dbo].[SomeStoredProcedure]";

connection.Open();
var result = cmd.ExecuteNonQuery();

Этот код можно сократить, но я думаю, что эта версия немного удобнее для отладки и пошагового выполнения.

Я не верю, что клиент Sql обязательно является предпочтительным выбором, но я чувствовал, что этим, по крайней мере, стоит поделиться, если кто-то еще, имеющий аналогичные проблемы, попадет сюда через Google.

Вышеупомянутый код написан на C #, но концепция попытки переключения на Sql Client по-прежнему применяется. По крайней мере, попытка сделать это будет диагностической.


Интересно. Я думаю, вы можете отредактировать решение с помощью кода VB (есть переводчики кода), чтобы оно соответствовало тегам вопроса. Тем не менее, я проголосовал за него.
Лайош Арпад

1

Если вы не смогли найти Local DTC в службах компонентов, попробуйте сначала запустить этот сценарий PowerShell:

$DTCSettings = @(
"NetworkDtcAccess",               # Network DTC Access
"NetworkDtcAccessClients",        # Allow Remote Clients        ( Client and Administration)
"NetworkDtcAccessAdmin",          # Allow Remote Administration ( Client and Administration)
"NetworkDtcAccessTransactions",   #                (Transaction Manager Communication )
"NetworkDtcAccessInbound",        # Allow Inbound  (Transaction Manager Communication )
"NetworkDtcAccessOutbound" ,      # Allow Outbound (Transaction Manager Communication )
"XaTransactions",                 # Enable XA Transactions
"LuTransactions"                  # Enable SNA LU 6.2 Transactions
)
foreach($setting in $DTCSettings)
{
Set-ItemProperty -Path HKLM:\Software\Microsoft\MSDTC\Security -Name $setting -Value 1
} 
Restart-Service msdtc

И оказывается!

Источник: менеджер транзакций партнеров отключил поддержку удаленных / сетевых транзакций.


0

Если у других такая же проблема:

У меня была аналогичная ошибка. Оказалось, что я обертывал несколько операторов SQL в транзакции, где один из них выполнялся на связанном сервере (оператор слияния в операторе EXEC (...) AT Server). Я решил проблему, открыв отдельное соединение со связанным сервером, инкапсулируя этот оператор в try ... catch, а затем прервав транзакцию в исходном соединении в случае срабатывания catch.


0

У меня было такое же сообщение об ошибке. Для меня изменение pooling=Falseна ;pooling=true;Max Pool Size=200в строке подключения устранило проблему.


Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.