Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/269.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 忽略特定查询的TransactionScope_C#_Entity Framework_Transactions_Entity Framework 5_Transactionscope - Fatal编程技术网

C# 忽略特定查询的TransactionScope

C# 忽略特定查询的TransactionScope,c#,entity-framework,transactions,entity-framework-5,transactionscope,C#,Entity Framework,Transactions,Entity Framework 5,Transactionscope,我正在寻找一种在TransactionScope处于活动状态时执行查询的方法,并忽略TransactionScope-基本上,我希望无论发生什么情况都执行这个特定的查询 我首先使用EF代码,按照应用程序的设计方式,在一次调用中多次打开一个新的数据上下文,每个都有自己的更改,所有这些都包含在一个TransactionScope中,假设没有失败,该TransactionScope最后调用了Complete()。在上下文内部,我们已经覆盖了SaveChanges,这样,如果base.SaveChang

我正在寻找一种在TransactionScope处于活动状态时执行查询的方法,并忽略TransactionScope-基本上,我希望无论发生什么情况都执行这个特定的查询

我首先使用EF代码,按照应用程序的设计方式,在一次调用中多次打开一个新的数据上下文,每个都有自己的更改,所有这些都包含在一个TransactionScope中,假设没有失败,该TransactionScope最后调用了
Complete()
。在上下文内部,我们已经覆盖了
SaveChanges
,这样,如果
base.SaveChanges()
上发生任何异常,我们可以捕获它并在回滚事务之前登录到数据库

由于
SaveChanges
发生在事务内部,日志显然不会发生,因为它与原始调用属于同一事务。我试图完全忽略TransactionScope,只是为了记录代码

下面是一些精简的代码:

// From the context
public override int SaveChanges() {
    try {
        return base.SaveChanges();
    } catch (Exception ex) {

        // Writes to the log table - I want this to run no matter what
        LogRepo.Log(/*stuff to log from the context*/);

        throw;
    }
}

// Inside the business logic
public void DoSomething() {
    try {
        using (var scope = new TransactionScope()) {

            using (var context = new FooContext()) {
                // Do something
                context.SaveChanges();
            }
            using (var context = new FooContext()) {
                // Do something else
                context.SaveChanges();
            }

            scope.Complete();
        }
    } catch (Exception ex) {
        // scope.Complete is never called, so the transaction is rolled back
    }
}
我尝试使用常规ADO.NET而不是EF进行日志记录,但结果仍然相同——它也会回滚


我需要在
SaveChanges
内部进行错误处理,因为我要记录的是正在保存的实体的状态,所以我不能简单地将日志移动到其他地方。我可以在
SaveChanges-catch
中构建消息,然后抛出它并让
DoSomething-catch
记录它,但是有几十种
DoSomething
方法,我更愿意只在一个地方处理这个问题。

这只是我最初的想法,但您需要将日志报告放在它自己的数据上下文(DC2)上这样周围的TransactionScope(使用DC1)就不会在未提交时回滚它

基本上,您需要使日志记录成为独立的、原子的


再看一看,在我看来,如果您将日志从SaveChanges移出到DoSomething()上的catch()中,您的日志记录就可以工作了。但是,您的日志记录仍然需要是独立的和原子化的。

我发现了一个我不太满意的解决方案,但似乎很有效。TransactionScope显然只影响当前线程,因此使用新线程进行日志记录似乎可以

public override int SaveChanges() {
    try {
        return base.SaveChanges();
    } catch (Exception ex) {

        string message = /*stuff to log from the context*/;
        new Thread(msg => {    

            LogRepo.Log(msg);

        }).Start(message);

        throw;
    }
}

如果在启用抑制选项的情况下将日志调用包装在另一个事务作用域内,则不会使用事务作用域

public override int SaveChanges() {
    try {
        return base.SaveChanges();
    } catch (Exception ex) {
        using (var scope = new TransactionScope(TransactionScopeOption.Suppress)) {
            LogRepo.Log(message); // stuff to log from the context
        }

        throw;
    }
}

TransactionScope围绕其内部的每个数据上下文进行包装-LogRepo确实创建了自己的全新上下文,但它仍然被TransactionScope拾取。对于您的编辑-我提到过-我至少需要从内部
SaveChanges
构建错误消息,因为我需要访问打开的数据上下文,但是,即使我从那里构建消息并将其发送给调用者,我仍然需要在调用者中执行几十次日志记录,并且我正试图将其全部保存在一个地方。是的,很明显,您的实现无法按设计工作。另一种选择是使用LogRepo并使其成为一个单例,在应用程序启动时创建,并在所有事务范围之外创建自己的DBContext。这不是最干净的设计,但它可以让您绕过TransactionScope业务。我还没有找到一种方法来从事务范围中“取消”上下文……谢谢-我不认为在整个应用程序的生命中保持开放的上下文是很舒服的,但是我会考虑它。它确实有一种“令人毛骨悚然”的感觉,但是如果它能起作用,它就会起作用。有点像我的单身建议。我也不喜欢它,但它肯定会起作用。@JoeBrunscheon+1代表“icky”:)调试时没问题。但在发布模式或运行模式下,它不起作用:(完美!正是我想要的。经过测试,它在常规ADO.NET和实体框架中都能工作。谢谢。刚刚实现了这个,现在我得到了这个错误:分布式事务管理器的网络访问(MSDTC)已禁用。请使用组件服务管理工具在MSDTC的安全配置中为网络访问启用DTC。我了解到打开多个事务可能会导致此错误?这让我省去了很多麻烦!我正在事务中处理MSMQ消息,但需要联系SQL Azure进行一点访问xtra数据,它们不支持DTC。使用它可以使我的事务仍能工作,同时还能让Azure正常工作。