2013-07-22 3 views
0

Мне удалось создать тестовое приложение, используя Rhino Service Bus и Sql Server Express. У меня есть внешний интерфейс MVC 4, который создает сообщение и отправляет его в очередь, а также создает запись в моей таблице базы данных. У меня есть служба Windows, которая захватывает сообщения из очереди и записывает в отдельную таблицу базы данных. Я хочу, чтобы сообщение send/database write было всем или ничего. Например, если ошибка отправки сообщения или запись базы данных не удалась, я хочу иметь возможность отбросить их обратно. Я попробовал обернуть их обоих в TransactionScope, но, основываясь на моих тестах, сообщения отправляются в очередь, даже без scope.Complete.Операции с Rhino Service Bus

Возможно ли это? Если да, может кто-нибудь указать мне в правильном направлении?

FYI ... Очереди MSMQ транзакционные очереди

Спасибо.

ответ

1

Я отправил ту же самую проблему на сайт Google Groups службы Rhino Service Bus и получил ответ от Орена. Оказывается, RSB будет работать с транзакциями, но я использовал IOnewayBus, который не использует DTC. Я внес изменения в использование IStartableServiceBus, и теперь все работает так, как я ожидал.

0

У нас была проблема с шиной обслуживания Rhino, в результате которой все транзакции включались в транзакцию с окружающими (MSDTC). Это было нормально, но мы запускаем ряд длительных процессов, которые занимают больше часа (DTC имеет максимальный тайм-аут в течение одного часа). Для того, чтобы обойти эту проблему, я создал реализацию IMessageModule, как показано ниже:

/// <summary> 
/// alows commands to opt-in to ambient transaction (MSDTC) 
/// </summary> 
/// <remarks>will supress by default</remarks> 
public class SuppressAmbientTransactionMessageModule : IMessageModule 
{ 

    [ThreadStatic] 
    private static TransactionScope transactionScope; 

    public void Init(ITransport transport, IServiceBus serviceBus) 
    { 
     transport.MessageArrived += TransportOnMessageArrived; 
     transport.BeforeMessageTransactionCommit += transport_BeforeMessageTransactionCommit; 
     transport.BeforeMessageTransactionRollback += transport_BeforeMessageTransactionCommit; 
    } 

    public void transport_BeforeMessageTransactionCommit(CurrentMessageInformation currentMessageInformation) 
    { 
     if (!(currentMessageInformation.Message is IWithAmbientTransaction)) 
     { 
      transactionScope.Dispose(); 
     } 
    } 

    public void Stop(ITransport transport, IServiceBus bus) 
    { 
     transport.MessageArrived -= TransportOnMessageArrived; 
     transport.BeforeMessageTransactionCommit -= transport_BeforeMessageTransactionCommit; 
     transport.BeforeMessageTransactionRollback -= transport_BeforeMessageTransactionCommit; 
    } 

    public bool TransportOnMessageArrived(CurrentMessageInformation currentMessageInformation) 
    { 
     if (!(currentMessageInformation.Message is IWithAmbientTransaction)) 

     { 
      transactionScope = new TransactionScope(TransactionScopeOption.Suppress); 
     } 
     return false; 
    } 
} 

Я также создал интерфейс беспорядочного под названием IWithAmbientTransaction, чтобы включить конкретную команду, чтобы привлечь в окружающих сделках. В то время как его не идеально подходит для такого долгого подхода к процессу работы, он решил наши непосредственные проблемы долгосрочных транзакций