2015-09-27 4 views
1

У нас есть обработчик, который выполняет как предполагается, когда он получил сообщение. В этом процессе есть несколько шагов, и каждый последовательный создает свой собственный новый контекст, как показано ниже.Как предотвратить NServiceBus от отката транзакции или ее частей?

public void Handle(SomeMessage message) 
{ 
    ... 
    try 
    { 
    ... 
    using(DataContext context = new DataContext()) { ... } 
    ... 
    using(DataContext context = new DataContext()) { ... } 
    ... 
    } 
    catch (Exception exception) 
    { 
    ... 
    using(DataContext context = new DataContext()) { ... } 
    ... 
    } 
} 

Однако порой исключение бросается и попадает в него. Текущая транзакция откатывается (и поскольку она явно не реализована мной, я предполагаю, не будучи абсолютно уверенным, что это выполняется самим NServiceBus, потому что все результаты, записанные в БД, исчезают, в том числе в catch заявление).

На данный момент я разрешаю это, записывая файл, когда что-то происходит ужасно, но я бы хотел, чтобы это было сохранено в БД.

Итак, в конечном счете, я хотел бы предотвратить, что последняя операция, одна в catch заявление, откат. Может ли это сделать, и если да, то как?

+0

Вы сказали, что как код, который вы отправили, не принадлежит вам? – Hopeless

+0

@Hopeless Не уверен, что вы имеете в виду. Код не является моим юридическим лицом, потому что он принадлежит компании, над которой я работаю. Но это мое в том смысле, что я это написал. (Ну, команда больше, чем я, конечно, но эта конкретная часть - это в основном я.) Неужели я не понимаю ваш вопрос? Я не настраивал автобус (и тот парень, который давно ушел). –

+0

Вы имеете в виду, что «последняя операция» - это то, что сделано в 'using (DataContext context = new DataContext()) {...}' (внутри catch) или *** все *** внутри catch? Я имею в виду, что я не понимаю, что вы на самом деле хотите предотвратить (последнее предложение). – Hopeless

ответ

6

Мне бы очень хотелось узнать более крупную проблему, чего вы пытаетесь достичь? Почему вы хотите что-то записывать в базу данных при возникновении ошибки? Если это связано с техническим аспектом, сообщения должны появиться в очереди ошибок, вы должны исправить ошибку и NServiceBus повторить сообщения. Когда это связано с бизнесом, у вас должен быть альтернативный маршрут для обработки конкретных бизнес-требований. Например, у вас нет на складе определенного товара, тогда может быть лучше отправить по электронной почте покупателю, чтобы дождаться своего товара или сказать им, что они могут вернуть свои деньги. И сообщите продажам, что кто-то купил товар на складе или что-то в этом роде.

NServiceBus действительно откатывает все транзакции, но это вопрос TransactionScope. Начните новый TransactionScope и скажите, что это новая корневая транзакция.

using(TransactionScope scope1 = new TransactionScope()) 
//Default is Required 
{ 
    using(TransactionScope scope2 = new 
     TransactionScope(TransactionScopeOption.Required)) 
    { 
    ... 
    } 

    using(TransactionScope scope3 = new TransactionScope(TransactionScopeOption.RequiresNew)) 
    { 
    ... 
    } 

    using(TransactionScope scope4 = new 
     TransactionScope(TransactionScopeOption.Suppress)) 
    { 
    ... 
    } 
} 

Сделка по объему3 является сделкой самостоятельно. Если хотите, поместите это в область захвата.

This article объясняет все это. Но опять же, я бы предпочел получить больше информации о том, чего вы на самом деле пытаетесь достичь. И, возможно, прочитал this article.

+1

Вы задаете ряд интересных предложений по вашим вопросам. Вы лаяете по правильному дереву, указывая на разделение ошибок из-за технических соображений и бизнес-логики. В нашем случае они не применимы непосредственно **, но ** определенная адаптация этих ** действительно **. Определенно +1 для этого. –