无法访问已处置的对象.交易

Shi*_*iji 4 c# entity-framework transactions transactionscope

我们正在使用Entity Framework并在事务范围内运行单元测试.我们原来在标题中得到了错误.

我设法将问题与某些问题隔离开来.

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
    }
}
Run Code Online (Sandbox Code Playgroud)

我们当前得到的错误是"操作对事务状态无效......"

如果我删除事务scope2,一切正常.

如果我将范围2标记为环境事务,它也可以正常工作.

Ste*_*pel 9

你是没有明确的创建scope2 TransactionScopeOption参数,它产生的默认TransactionScopeOption.Required,见备注TransactionScope Constructor

此构造函数创建一个新的事务作用域,其事务作用域选项等于Required.这意味着新范围需要事务,并且如果已存在环境事务,则使用环境事务.否则,它会在进入范围之前创建新事务.

在您的示例中,环境TransactionScope确实已经存在(scope1),因此具有隐式参数的新嵌套TransactionScope(scope2)TransactionScopeOption.Required使用现有环境事务而不是创建新事务本身.

但是,隐式事务语义scope2仍然存在,因此创建的现有环境事务将被scope1中止,因为您没有Complete在最后调用scope2:

无法调用此方法会中止事务,因为事务管理器将此解释为系统故障,或等效于事务范围内引发的异常

当然,如果您删除scope2或更改其语义TransactionScopeOption.RequiresNew(意味着"始终为范围创建新事务."),问题会立即消失,因为创建的现有环境事务scope1将不再受到影响.

有关详细信息,请参阅使用事务范围实现隐式事务.