忽略TransactionScope以进行特定查询

我正在寻找一种在TransactionScope处于活动状态时执行查询的方法,并忽略TransactionScope – 基本上,我想执行此特定查询,无论如何。

我首先使用EF代码,并且设计应用程序的方式,在一次调用中多次打开一个新的数据上下文,每个都有自己的更改,所有这些都包含在一个TransactionScope中,它具有Complete()假设没有失败,最后调用Complete() 。 在上下文中,我们重写了SaveChanges以便在base.SaveChanges()上发生任何exception时,我们可以捕获它并在回滚事务之前登录到数据库。

由于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内部进行error handling,因为我正在记录的是正在保存的实体的状态 – 所以我不能轻易地将日志记录移动到其他地方。 我可以在SaveChanges catch内部构建消息,抛出它并让DoSomething catch它,但是有几十种DoSomething方法,我宁愿在一个地方处理这个问题。

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

 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; } } 

只是我最初的想法,但你需要将你的LogRepo放在它自己的DataContext(DC2)上,以便周围的TransactionScope(带有DC1)在它没有提交时不会回滚它。

基本上,您需要使您的日志记录自包含且primefaces化。

编辑在查看它时,在我看来,如果您将Logging从SaveChanges移动到DoSomething()上的catch(),您的日志记录将起作用。 但是,您的日志记录仍然需要自包含和primefaces化。

我找到了一个我不满意的解决方案,但似乎有效。 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; } }