I have a ton of rather working code that's been here for months and today I saw the following exception logged:
我有很多相当工作的代码已经存在了几个月,今天我看到记录了以下异常:
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
and I'd like to investigate why this exception was thrown. I've read MSDN description of BeginTransaction()
and all it says is that well, sometimes this exception can be thrown.
我想调查为什么抛出这个异常。我已经阅读了关于BeginTransaction()的MSDN描述,并且它说的很好,有时可以抛出这个异常。
What does this exception mean exactly? What is the deficiency in my code that I should be looking for?
这个例外究竟意味着什么?我应该寻找的代码有什么不足之处?
2 个解决方案
#1
18
You'll get this if the connection already has an uncommitted transaction and you call BeginTransaction again.
如果连接已经有未提交的事务并且您再次调用BeginTransaction,则会得到此信息。
In this example:
在这个例子中:
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();
}
}
}
}
... I get exactly the same exception at the second BeginTransaction.
...我在第二个BeginTransaction得到完全相同的异常。
Make sure the first transaction is committed or rolled back before the next one.
确保第一个事务在下一个事务之前提交或回滚。
If you want nested transactions, you might find TransactionScope is the way forward.
如果您想要嵌套事务,您可能会发现TransactionScope是前进的方向。
#2
11
The same problem occurs when using the 'wrong' method for a transaction, this happened after we upgraded to a newer version of the Entity Framework.
使用'错误'方法进行事务时会出现同样的问题,这是在我们升级到较新版本的Entity Framework之后发生的。
In the past we were using the following method to create a transaction and mixed EF strong typed linq queries with Sql queries, but since the Connection
property did not exist anymore, we replaced all db.
with db.Database
, which was wrong:
在过去,我们使用以下方法创建事务并使用Sql查询混合EF强类型linq查询,但由于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
}
Somewhere they changed the behaviour of that transaction method behaviour with a newer version of the Entity Framework and the solution is to use:
在某个地方,他们使用较新版本的Entity Framework更改了该事务方法行为的行为,解决方案是使用:
db.Database.Connection.Open();
using (var transaction = db.Database.BeginTransaction())
{
// do stuff inside transaction
}
Notice that the transaction is now callen on Database
instead of Connection
.
请注意,事务现在在Database而不是Connection上进行了callen。
#1
18
You'll get this if the connection already has an uncommitted transaction and you call BeginTransaction again.
如果连接已经有未提交的事务并且您再次调用BeginTransaction,则会得到此信息。
In this example:
在这个例子中:
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();
}
}
}
}
... I get exactly the same exception at the second BeginTransaction.
...我在第二个BeginTransaction得到完全相同的异常。
Make sure the first transaction is committed or rolled back before the next one.
确保第一个事务在下一个事务之前提交或回滚。
If you want nested transactions, you might find TransactionScope is the way forward.
如果您想要嵌套事务,您可能会发现TransactionScope是前进的方向。
#2
11
The same problem occurs when using the 'wrong' method for a transaction, this happened after we upgraded to a newer version of the Entity Framework.
使用'错误'方法进行事务时会出现同样的问题,这是在我们升级到较新版本的Entity Framework之后发生的。
In the past we were using the following method to create a transaction and mixed EF strong typed linq queries with Sql queries, but since the Connection
property did not exist anymore, we replaced all db.
with db.Database
, which was wrong:
在过去,我们使用以下方法创建事务并使用Sql查询混合EF强类型linq查询,但由于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
}
Somewhere they changed the behaviour of that transaction method behaviour with a newer version of the Entity Framework and the solution is to use:
在某个地方,他们使用较新版本的Entity Framework更改了该事务方法行为的行为,解决方案是使用:
db.Database.Connection.Open();
using (var transaction = db.Database.BeginTransaction())
{
// do stuff inside transaction
}
Notice that the transaction is now callen on Database
instead of Connection
.
请注意,事务现在在Database而不是Connection上进行了callen。