2013-10-24 3 views
21

У меня есть тонна, а рабочий код, который был здесь в течение нескольких месяцев, и сегодня я увидел следующее исключение: вошлиКогда происходит «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(), и все, что он говорит, это хорошо, иногда это исключение можно выбросить.

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

+0

Вы используете обычный SqlConnection/SqlCommmand/SqlDataAdapter или используете ORM (например, EF или L2S или другие)? И код с использованием явных транзакций или TransactionScopes? Кроме того, можете ли вы отправить образец кода вокруг ошибки, которая регистрирует/бросает исключение? – SimonGoldstone

+0

Отметьте этот ответ: http://stackoverflow.com/questions/407320/strange-sql2005-problem-sqlconnection-does-not-support-parallel-transactions Речь идет о той же проблеме. – LawfulHacker

+0

@SimonGoldstone: Если бы я мог сузить проблему, я бы не стал задавать этот вопрос. Я не прошу «мой код не работает, пожалуйста, помогите, как можно скорее», я спрашиваю, что мне нужно искать в моем коде. – sharptooth

ответ

17

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

10

Такая же проблема возникает при использовании «неправильного» метода для транзакции, это произошло после того, как мы обновились до более новой версии 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.

+0

Это решение решило мою проблему, так как я использую первую модель базы данных EF, и я использовал «соединение без транзакций» для выполнения запросов к другим таблицам в транзакции. –

+0

Я обнаружил, что TransactionScope очень хорошо работает и внутри EF. Я не использовал BeginTransaction уже давно. Практически все мои транзакционные работы выполняются внутри TransactopScopes. – SimonGoldstone

+4

Спасибо за публикацию этого. У меня была точно такая же проблема. +1, хотя это не ответ на конкретную ситуацию ОП. – Raithlin

Смежные вопросы