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