Ошибка "Операция недопустима для состояния транзакции" и объем транзакции

При попытке вызвать хранимую процедуру, содержащую инструкцию SELECT, я получаю следующую ошибку:

The operation is not valid for the state of the transaction

Вот структура моих звонков:

public void MyAddUpdateMethod()
{

    using (TransactionScope Scope = new TransactionScope(TransactionScopeOption.RequiresNew))
    {
        using(SQLServer Sql = new SQLServer(this.m_connstring))
        {
            //do my first add update statement

            //do my call to the select statement sp
            bool DoesRecordExist = this.SelectStatementCall(id)
        }
    }
}

public bool SelectStatementCall(System.Guid id)
{
    using(SQLServer Sql = new SQLServer(this.m_connstring)) //breaks on this line
    {
        //create parameters
        //
    }
}

Проблема в том, что я создаю другое соединение с той же базой данных в рамках транзакции?

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
66
0
101 054
6
Перейти к ответу Данный вопрос помечен как решенный

Ответы 6

Я столкнулся с этой ошибкой, когда моя транзакция вложена в другую. Возможно ли, что хранимая процедура объявляет собственную транзакцию или вызывающая функция объявляет ее?

У меня нет кода транзакции t-sql ни в одной из хранимых процедур. Теоретически транзакция должна контролироваться MyAddUpdateMethod ()

Michael Kniskern 11.10.2008 02:04

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

codeMonkey 28.03.2017 19:48
Ответ принят как подходящий

После некоторого исследования мне кажется, что я не могу открыть два соединения с одной и той же базой данных с помощью блока TransactionScope. Мне нужно было изменить свой код, чтобы он выглядел так:

public void MyAddUpdateMethod()
{
    using (TransactionScope Scope = new TransactionScope(TransactionScopeOption.RequiresNew))
    {
        using(SQLServer Sql = new SQLServer(this.m_connstring))
        {
            //do my first add update statement            
        }

        //removed the method call from the first sql server using statement
        bool DoesRecordExist = this.SelectStatementCall(id)
    }
}

public bool SelectStatementCall(System.Guid id)
{
    using(SQLServer Sql = new SQLServer(this.m_connstring))
    {
        //create parameters
    }
}

Я наткнулся на ту же ситуацию. Мне пришлось обратиться к двум разным базам данных в рамках одной и той же области транзакции. Спасибо за совет.

rageit 09.04.2012 16:52

Хорошая уловка, обычное место, чтобы увидеть это, - это если у вас есть среда ведения журнала (nlog, log4net), которая выполняет запись в БД, поскольку структура ведения журнала создаст собственное соединение с базой данных в качестве вашего приложения.

viggity 11.07.2012 18:28

Приложения регистрации должен, вероятно, подавляют любой внешний контекст TransactionScope.

user2864740 19.01.2017 10:35

NLog подавляет любую внешнюю TransactionScope: github.com/NLog/NLog/wiki/Database-target

Alex 17.10.2019 18:40

Я дважды открывал одно и то же соединение с помощью операторов using в том же TransactionScope, но все еще работал. Я использовал SqlConnection вместо SQLServer, как в вашем примере выше.

Rajaram Shelar 21.12.2020 15:25

Я также столкнулся с той же проблемой, я изменил тайм-аут транзакции на 15 минут, и он работает. Надеюсь, это поможет.

TransactionOptions options = new TransactionOptions();
options.IsolationLevel = System.Transactions.IsolationLevel.ReadCommitted;
options.Timeout = new TimeSpan(0, 15, 0);
using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required,options))
{
    sp1();
    sp2();
    ...

}

Я сильно подозреваю, что поведение изменилось не из-за тайм-аута, а из-за того, что вы изменили уровень изоляции с Serializable на ReadCommitted.

Nine Tails 27.05.2015 13:21

Когда я столкнулся с этим исключением, было InnerException «Время ожидания транзакции». Поскольку это было во время сеанса отладки, когда я на некоторое время остановил свой код внутри TransactionScope, я решил проигнорировать эту проблему.

Когда это конкретное исключение с тайм-аутом появляется в развернутом коде, я думаю, что следующий раздел в вашем файле .config поможет вам:

<system.transactions> 
        <machineSettings maxTimeout = "00:05:00" /> 
</system.transactions>

То же, что и TransactionOptions.Timeout?

Kiquenet 27.09.2018 13:49

Обратите внимание, что есть конфигурация .NET framework, которая отменяет это, когда это более 10 минут!

DdW 19.08.2020 20:35

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

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

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

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

  1. Добавьте правила брандмауэра, чтобы ваши машины могли общаться друг с другом.
  2. Убедитесь, что служба координатора распределенных транзакций работает
  3. Включите доступ к сети dtc. Запустите dcomcnfg. Перейдите в Компонентные службы> Мой компьютер> Координатор распределенных транзакций> Локальный DTC. Щелкните правой кнопкой мыши свойства.
  4. Включите доступ к сети DTC, как показано.

Важный: не редактируйте / не меняйте учетную запись пользователя и пароль в поле учетной записи DTC Logon, оставьте все как есть, в конечном итоге вам придется переустановить Windows, если вы это сделаете.

DTC photo

Это было исправлением нашей ситуации. Спасибо!

Jaans 18.01.2021 14:07

Другие вопросы по теме