Когда происходит "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() и все это говорит о том, что иногда это исключение может быть брошено.

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

2 ответов


вы получите это, если соединение уже имеет незафиксированную транзакцию, и вы снова вызываете 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 - это путь вперед.


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

в прошлом мы использовали следующий метод для создания транзакции и смешанных EF strong типизированных запросов 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
}

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