如何从 .Net 中的 TransactionScope 中正确排除日志记录
我有一些这样的代码:(
using (var scope = GetTransactionScope())
{
... do stuff
InfoLogger.LogInformation("blah blah", "Blah blah", someEventId);
}
注意:GetTransactionScope() 获取交易)。
但我不想在事务中涉及日志记录调用; LogInformation()
调用包装对企业库的调用。
据我了解,我需要使用 Suppress
TransactionScopeOption 从事务中排除日志记录调用(这是唯一/最好的方法)?
假设是这种情况,我宁愿在我的助手内部执行此操作 - 否则我将在整个地方拥有一辆大型 SUV 的额外 TransactionScope 代码......那么,这是最好的方式/可接受的方式:
public static void LogInformation(string title, string message, int eventId)
{
using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Suppress))
{
... do the real logging.
}
}
I have some code like this:
using (var scope = GetTransactionScope())
{
... do stuff
InfoLogger.LogInformation("blah blah", "Blah blah", someEventId);
}
(NB: GetTransactionScope() gets me the transaction).
But I don't want to involve the logging call in the transaction; the LogInformation()
call wraps a call to the Enterprise Libraries.
From what I understand I need to use the Suppress
TransactionScopeOption to exclude the logging call from the transaction (is that the only / best way)?
Assuming that's the case I'd rather do this inside my helper - otherwise I'm going to have a large SUV's worth of additional TransactionScope code all over the place... So, is this the best way / acceptable:
public static void LogInformation(string title, string message, int eventId)
{
using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Suppress))
{
... do the real logging.
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
是的,使用
Suppress
选项意味着“进行真正的日志记录”发生在事务上下文之外。但这在一定程度上取决于您记录的内容以及原因;另一种方法是将所有日志记录数据放入生产者/消费者队列(即由单独线程提供服务的线程安全队列)。因为
TransactionScope
是线程绑定的,这会删除您的事务关联,但它也具有删除日志记录作为操作本身的一个因素(延迟等)的优点,并允许您可以选择批量记录操作。显然,这仅适用于信息日志记录,因为(在边缘情况下)队列中的少量数据在回收等过程中可能会丢失。
生产者/消费者方法是特别如果您要记录到文件,因为它允许您同步对文件的访问(这显然是必要的),而无需阻塞 IO 本身(您只需同步对队列的访问) )。
Yes, using the
Suppress
option will mean that "do the real logging" happens outside of the transaction context.But it depends a little bit on what you are logging and why; one other approach is to throw all your logging data onto a producer/consumer queue (i.e. a thread-safe queue serviced by a separate thread). Because
TransactionScope
is thread-bound this removes your transaction association, but it also has the advantage of removing the logging as a factor (latency etc) in the operation itself, and allows you to batch up the logging operations if you choose.Obviously this would only apply to informational logging, as there is a chance (in edge cases) that a small amount of data from the queue will be lost during recycles etc.
The producer/consumer approach is particularly enticing if you are logging to a file, as it allows you to synchronize access to the file (which is obviously necessary), without the need to block on the IO itself (you are only synchronizing access to the queue).