我们使用实体框架并在事务范围内运行单元测试。我们最初在标题上有错误。
我设法把这个问题分离出来了。
using (TransactionScope scope1 = new TransactionScope())
{
using (TransactionScope scope2 = new TransactionScope())
{
// Here there is no code
}
using (Entities se = new Entities())
{
EntityConnection entityConnection = (EntityConnection)se.Connection;
DbConnection storeConnection = entityConnection.StoreConnection;
storeConnection.Open(); // On this line the error occurs
// Some code that runs a stored procedure
}
}
我们当前得到的错误是“操作对事务的状态无效…”
如果删除事务作用域2,一切正常。
如果我将作用域2标记为环境事务,它也可以正常工作。
最佳答案
您创建的scope2没有显式的TransactionScopeOption
参数,其默认值为TransactionScopeOption.Required
,请参见TransactionScope Constructor
中的“备注”部分。
此构造函数创建一个新的
事务的事务范围
作用域选项等于必需的。这个
意味着交易是必需的
新的范围和环境
如果已使用事务
存在。否则,它将创建一个新的
进入作用域之前的事务。
在您的示例中,环境TransactionScope
确实已经存在(scope1
),因此新的嵌套TransactionScope
(scope2
)具有隐式参数TransactionScopeOption.Required
正在使用现有的环境事务,而不是创建新的事务本身。
但是,scope2
的隐式事务语义仍然存在,因此,scope1
所创建的现有环境事务将被中止,因为在Complete
结束时,您没有调用scope2
:
调用此方法失败将中止
交易,因为交易
经理将此解释为一个系统
失败,或等同于异常
在事务范围内引发
当然,如果删除scope2
或将其语义更改为TransactionScopeOption.RequiresNew
(意味着‘新的事务总是为范围创建’),问题马上就会发生,因为由scope1
创建的现有环境事务将不再受到影响。
请参见Implementing an Implicit Transaction using Transaction Scope了解有关此的详细信息。