我有很多相当工作的代码已经存在了好几个月,今天我看到了以下异常记录:
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
我想调查抛出此异常的原因。我已经阅读了BeginTransaction()
的MSDN描述,并且它说的很好,有时可以抛出此异常。
这个例外究竟意味着什么?我应该寻找的代码缺点是什么?
答案 0 :(得分:19)
如果连接已经有一个未提交的事务并且你再次调用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是前进之路。
答案 1 :(得分:11)
对事务使用“错误”方法时会出现同样的问题,这是在我们升级到较新版本的Entity Framework之后发生的。
过去我们使用以下方法创建事务并使用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
}
在某个地方,他们使用较新版本的Entity Framework更改了该事务方法行为的行为,解决方案是使用:
db.Database.Connection.Open();
using (var transaction = db.Database.BeginTransaction())
{
// do stuff inside transaction
}
请注意,该交易现在已在Database
而非Connection
上进行了广告。