如何在.Net中正确地从TransactionScope中排除日志记录

时间:2011-04-27 05:42:23

标签: .net logging transactions transactionscope

我有一些像这样的代码:

using (var scope = GetTransactionScope())
{
  ... do stuff
  InfoLogger.LogInformation("blah blah", "Blah blah", someEventId);
}

(注意:GetTransactionScope()让我得到了交易)。

但我不希望在事务中涉及日志记录调用; LogInformation()调用包装了对企业库的调用。

根据我的理解,我需要使用Suppress TransactionScopeOption从事务中排除日志记录调用(这是唯一/最佳方式)吗?

假设是这样的话,我宁愿在我的助手里面这样做 - 否则我将会在整个地方拥有一个大型SUV的额外TransactionScope代码...所以,这是最好的方式/可接受的:< / p>

public static void LogInformation(string title, string message, int eventId)
{
    using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Suppress))
    {
        ... do the real logging.
    }
}

1 个答案:

答案 0 :(得分:4)

是的,使用Suppress选项意味着“执行真正的日志记录”发生在事务上下文之外。

但这取决于你记录的内容和原因;另一种方法是将所有日志记录数据抛出到生产者/消费者队列(即由单独的线程服务的线程安全队列)。由于TransactionScope是线程绑定的,因此会删除您的事务关联,但它还具有在操作本身中删除 logging 作为因素(延迟等)的优势,并允许您批处理如果您选择,请记录日志记录操作。

显然,这只适用于信息日志记录,因为在边缘情况下,有可能在回收期间丢失队列中的少量数据。

如果您正在登录文件,生产者/消费者方法特别诱人,因为它允许您同步对文件的访问(这显然是必要的),而不需要阻止IO本身(您只是同步对队列的访问)。