Менеджер транзакцій вимкнув підтримку віддалених / мережевих транзакцій


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», «Дозволити віддаленого клієнта», «Дозволити вхідний / вихідний» та «Увімкнути ПОРАДУ».

Щоб увімкнути мережевий доступ до DTC для транзакцій MS DTC

  1. Відкрийте оснастку Служби компонентів.

    Щоб відкрити Служби компонентів, натисніть кнопку Пуск. У полі пошуку введіть dcomcnfg і натисніть клавішу ENTER.

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

  3. У меню Дія натисніть Властивості.

  4. Клацніть на вкладку Безпека та внесіть такі зміни: У Налаштуваннях безпеки встановіть прапорець Доступ до мережі DTC.

    У Transaction Manager Communication встановіть прапорці Дозволити вхідні та Дозволити вихідні.


3
Дякую, Магнусе. Це має бути налаштування програми, оскільки цей тип транзакцій працював з однаковими комп’ютерами, а це означає, що ця проблема не пов’язана з машиною.
Лайош Арпад

Так. Він викликає той самий виняток.
Лайош Арпад,

Я думаю, це пов’язано з тим, що ви насправді робите всередині TransactionScope.
Магнус,

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

13
переконайтеся, що ви використовуєте одне і те ж відкрите підключення для всіх дзвінків до бази даних усередині транзакції.
Магнус

11

Я отримував це питання з перервами, я дотримувався інструкцій тут і дуже подібних в інших місцях. Все було налаштовано правильно.

Ця сторінка: http://sysadminwebsite.wordpress.com/2012/05/29/9/ допомогла мені знайти проблему.

В основному у мене були дублікати ідентифікаторів клієнтів для MSDTC на обох серверах. HKEY_CLASSES_ROOT \ CID

Див .: http://msdn.microsoft.com/en-us/library/aa561924.aspx розділ Переконайтеся, що MSDTC присвоєно унікальне значення CID

Я працюю з віртуальними серверами, і наша команда серверів любить використовувати одне і те ж зображення для кожного сервера. Це просте виправлення, і нам не потрібен був перезапуск. Але службі DTC потрібно було встановити значення Автоматичний запуск, і її потрібно було запустити після перевстановлення.


9

У мене була процедура зберігання, яка викликає іншу процедуру зберігання на "пов'язаному сервері". Коли я виконую її в sms, це було нормально, але коли я викликаю її в додатку (за Entity Framework), я отримав цю помилку. Ця стаття мені допомогла, і я використав цей сценарій:

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

докладніше розгляньте це: Зв’язаний сервер: Менеджер транзакцій партнера вимкнув підтримку віддалених / мережевих транзакцій


1
Посилання на рішення вітається, але будь ласка, переконайтесь, що ваша відповідь корисна без нього: додайте контекст навколо посилання, щоб ваші однодумці мали певне уявлення, що це таке і чому воно є, а потім цитуйте найбільш релевантну частину сторінки, яку ви “ повторне посилання на випадок, якщо цільова сторінка буде недоступна. Відповіді, які є лише кількома посиланнями, можуть бути видалені.
Петтер Фріберг,

1
Це вирішило мою проблему, тож дякую за надання цього. Я не знаю, чому він отримав -1 голос, оскільки він працював, щоб виправити мою конкретну проблему.
Бойд П

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

Коментар до відповіді : "переконайтеся, що ви використовуєте одне і те ж відкрите з'єднання для всіх дзвінків до бази даних всередині транзакції. - Magnus"

Наші користувачі зберігаються в окремому базі даних від даних, з якими я працював під час транзакцій. Відкриття з'єднання db для отримання користувачем спричинило цю помилку для мене. Переміщення іншого підключення db та пошуку користувача за межі області транзакції виправило помилку.


1

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

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

Менеджер транзакцій партнера вимкнув підтримку віддалених / мережевих транзакцій *

Перехід до клієнта SQL вирішив мою проблему, що також підтвердило для мене, що це стосується 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 Client - це бажаний вибір, але я вважав, що цим принаймні варто поділитися, якщо хтось, хто має подібні проблеми, потрапить сюди через Google.

Наведений вище код - це C #, але концепція спроби переходу на клієнт Sql все ще застосовується. Принаймні, це буде діагностичною спробою зробити це.


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

1

Якщо вам не вдалося знайти локальний 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). Я вирішив проблему, відкривши окреме підключення до пов’язаного сервера, інкапсулюючи цей оператор у спробі… catch, а потім припинив транзакцію на початковому з’єднанні на випадок, якщо злавиться.


0

У мене було таке саме повідомлення про помилку. Для мене перехід pooling=Falseдо ;pooling=true;Max Pool Size=200рядка з'єднання вирішив проблему.


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.