Я создал центральную систему ведения журнала для решения, которое включает маршрутизацию и обработку сообщений в нескольких частных очередях (MSMQ) с использованием WCF. В рамках метода контракта службы WCF я делаю некоторые записи. Вот несколько сокращенных кодов для иллюстрации:
[OperationBehavior(TransactionScopeRequired = true, TransactionAutoComplete = true)]
public void ReceiveMessage(MsmqMessage<MyMessageContainer> msg)
{
try{
Logger.Log(LogLevel.DEBUG, "Message Processing...");
// process the message here
Logger.Log(LogLevel.DEBUG, "Message Processed.");
}
catch(Exception exp) {
Logger.LogError(exp);
throw exp;
}
}
Ничто из этого не разрушает землю. Регистратор сам выполняет запись в транзакционную очередь, поэтому при возникновении исключения не только входящее сообщение помещается обратно в очередь, но сообщения регистратора не помещаются в их очередь. Чтобы все сообщения Logger записывались независимо от того, что происходит во внешней транзакции, я сделал следующее в методе Logger.Log (опять же, упрощенно):
public void Log(LogLevel level, string message)
{
using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Suppress))
{
// write message to log queue
}
}
Кажется, все это работает. Я знаю, что некоторые люди следуют философии «если это работает, это правильно», но я хотел бы знать, есть ли какие-либо серьезные недостатки в этом решении, или есть что-то лучшее, что я могу сделать? Примечание. Я развертываю код на MSMQ 3 и 4 и использую Framework v4.x.