How to correctly exclude logging from TransactionScope in .Net
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 L开发者_如何转开发ogInformation(string title, string message, int eventId)
{
using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Suppress))
{
... do the real logging.
}
}
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).
加载中,请稍侯......
精彩评论