Проверьте, находится ли соединение в транзакции

Я получаю SqlConnection does not support parallel transactions. исключение, и этот ответ упоминает его, когда соединение пытается открыть две транзакции. Это именно то, что я делаю. Я думал, что вложенные транзакции в порядке (я использовал sqlite для прототипа).

Как проверить, действительно ли соединение уже находится в транзакции? Я использую файл базы данных Microsoft SQL Server.

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

Чтобы узнать, есть ли соединение в настоящее время в транзакции, вы можете:

 var com = yourConnection.CreateCommand(); com.CommandText = "select @@TRANCOUNT"; var trancount = com.ExecuteScalar(); 

Это возвращает количество вложенных транзакций.

Обратите внимание, что вы можете выполнять транзакции вручную, не используя объект SqlTransaction. Например:

 var com = yourConnection.CreateCommand(); com.CommandText = "BEGIN TRANSACTION"; com.ExecuteNonQuery(); com.CommandText = "BEGIN TRANSACTION"; com.ExecuteNonQuery(); com.CommandText = "INSERT INTO TestTable (name) values ('Joe');"; com.ExecuteNonQuery(); com.CommandText = "COMMIT TRANSACTION"; com.ExecuteNonQuery(); com.CommandText = "ROlLBACK TRANSACTION"; com.ExecuteNonQuery(); com.CommandText = "SELECT COUNT(*) FROM TestTable"; Console.WriteLine("Found {0} rows.", com.ExecuteScalar()); 

Это печатает 0 , потому что вложенная транзакция полностью прервана.

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

Я думаю, что когда ваш код не знает, это сделает только Try / Catch. Какой язык?

Вы можете проверить, открыта ли транзакция, проверяя, является ли cmd.Transaction null .

Затем соответствующим образом заверните свой код, чтобы, если транзакция уже открыта, вызывающая функция владеет этой транзакцией и будет ее соответствующим образом скопировать.

 //begin transaction unless one was already started bool newTransaction = cmd.Transaction == null; if (newTransaction) cmd.Transaction = cmd.Connection.BeginTransaction(); try { // do Stuff Here cmd.ExecuteNonQuery(); cmd.ExecuteNonQuery(); // commit if it's our to commit if (newTransaction) cmd.Transaction.Commit(); } catch (SqlException ex) { if (newTransaction && cmd.Transaction != null) cmd.Transaction.Rollback(); throw; } 

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

Interesting Posts

Снижает ли безопасность учетных записей SQL для MS SQL Server 2008

Как получить дату начала диапазона дат, на сегодняшний день с одной даты в SQL Server

столбца для строки в sql-сервере?

ВЫБОР ЗАЯВЛЕНИЯ T-SQL КАК ПЕРЕМЕННЫЙ И РЕЗУЛЬТАТ В РЕЗУЛЬТАТЕ ДРУГИХ ПЕРЕМЕННЫХ

Excel VBA – Выполнение задания в SQL Server с помощью макроса

Масштабирование таблиц с разделами или с отдельными базами данных?

SQL Server 2008: TOP 10 и отчетливые

Примеры замечательных отчетов SSRS pdf

Как установить владельца существующей базы данных SQL Server

Значение datetime для SQL

как выполнять множественные агрегации по одному SQL-запросу

Структура Entity очень медленно загружается в первый раз после каждой компиляции

В настоящее время выполняется запрос в SQL Server

Может ли IFilters 2.0 полнотекстовый индексировать текст в диаграмме в документе Office 2007?

Как я могу отправить строку как NULL на SQLServer с помощью Dapper?

Давайте будем гением компьютера.