2
votes

I have an endpoint which receives messages and creates a saga in order to be able to response to that corresponding message at a later point in time. The message contains some xml document and this xml doc will be validated within this message handler. If we catch some validation errors, we create a message response (no saga involved) to inform the originating endpoint that something with the xml doc was wrong. In the case of a validation error, the saga is not stored as expected and as required. But I still want to reply to the originating endpoint. The problem is, that nservicebus also does a rollback on the reply.

Is there a way to go? I tried to wrap the reply into a new transaction scope, but this did not work:

        using (var scope = new TransactionScope(TransactionScopeOption.RequiresNew))
        {
            this.bus.Reply(message);

            scope.Complete();
        }

Any advice? Thanks in advance

Additional Information: The orginal problem was that I did not throw (or rethrow) any exception but replying to the originator in the catch section (I know its bad design).

The Saga is stored with a unique attribute applied on a id, which comes from the originating endpoint. And since I did not throw or pass any exception in the reply case (validation error occured), nservicebus always stored the saga. If the originating endpoint corrects the xml so that this is valid and resends a message (with the same id) nservicebus tries to store a new saga with the same id (causes concurrency exception on ravenDB because the saga with that unique property already exists). As a quick fix, I want to change the unique property and use instead the message id as the unique prop. In that case, I am sure that the message id is always unique and a saga concurrency exception could not happen again. Do you know if that causes any side effects?

1
Why do you need a rollback? Can you not do all of your validation up-front before touching any other resources? And just MarkAsComplete the saga so that it doesn't get persisted?Damien_The_Unbeliever
I marked the saga as complete in case of an error. Thank you very much!Fabian Trottmann

1 Answers

1
votes

You may be able to leverage the message handler pipeline. The first handler in your pipeline could do the validation and any response if necessary. During the validation, do not throw an exception, just reply. The second handler could initiate the Saga and set the state to be "Invalid" or something like that. My assumption is that you will get another request with valid data and then you will follow the "normal" process and set the state to "Valid" and continue on.