Подтвердить что ты не робот

Когда происходит "SqlConnection не поддерживает параллельные транзакции"?

У меня есть тонна довольно рабочего кода, который был здесь в течение нескольких месяцев, и сегодня я увидел следующее зарегистрированное исключение:

System.InvalidOperationException
SqlConnection does not support parallel transactions.
    at System.Data.SqlClient.SqlInternalConnection.BeginSqlTransaction(
       IsolationLevel iso, String transactionName)
    at System.Data.SqlClient.SqlConnection.BeginTransaction(
       IsolationLevel iso, String transactionName)
    at my code here

и я хотел бы выяснить, почему это исключение было брошено. Я прочитал описание MSDN BeginTransaction(), и все, что он говорит, это хорошо, иногда это исключение можно выбросить.

Что означает это исключение? Каков недостаток моего кода, который я должен искать?

4b9b3361

Ответ 1

Вы получите это, если соединение уже имеет незафиксированную транзакцию, и вы снова вызываете BeginTransaction.

В этом примере:

class Program
{
    static void Main(string[] args)
    {
        using (SqlConnection conn = new SqlConnection("Server=.;Database=TestDb;Trusted_Connection=True;"))
        {
            conn.Open();

            using (var tran = conn.BeginTransaction())
            {
                using (var cmd = new SqlCommand("INSERT INTO TESTTABLE (test) values ('" + DateTime.Now.ToString() + "')", conn))
                {
                    cmd.Transaction = tran;
                    cmd.ExecuteNonQuery();
                }

                using (var tran2 = conn.BeginTransaction())    // <-- EXCEPTION HERE
                {
                    using (var cmd = new SqlCommand("INSERT INTO TESTTABLE (test) values ('INSIDE" + DateTime.Now.ToString() + "')", conn))
                    {
                        cmd.Transaction = tran2;
                        cmd.ExecuteNonQuery();
                    }

                    tran2.Commit();
                }

                tran.Commit();
            }
        }
    }
}

... Я получаю точно такое же исключение во втором BeginTransaction.

Убедитесь, что первая транзакция зафиксирована или откат до следующего.

Если вы хотите вложенные транзакции, вы можете найти TransactionScope путь вперед.

Ответ 2

Такая же проблема возникает при использовании "неправильного" метода для транзакции, это произошло после того, как мы обновились до более новой версии Entity Framework.

В прошлом мы использовали следующий метод для создания транзакции и смешанных EF сильных типизированных запросов linq с запросами Sql, но поскольку свойство Connection больше не существовало, мы заменили все db. на db.Database, что было неправильно:

// previous code
db.Connection.Open();
using (var transaction = db.Connection.BeginTransaction())
{
    // do stuff inside transaction
}
// changed to the following WRONG code
db.Database.Connection.Open();
using (var transaction = db.Database.Connection.BeginTransaction())
{
    // do stuff inside transaction
}

Где-то они изменили поведение этого поведения метода транзакций с более новой версией Entity Framework, и решение должно использовать:

db.Database.Connection.Open();
using (var transaction = db.Database.BeginTransaction())
{
    // do stuff inside transaction
}

Обратите внимание, что транзакция теперь называется Database вместо Connection.