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).
精彩评论