Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I realize the above question probably raises a few 'what??'s, but let me try to explain :

I'm trying to wrap my head on a couple of related concepts, basically the Saga-pattern ( http://www.rgoarchitects.com/Files/SOAPatterns/Saga.pdf) in combination with Event-sourcing (A DDD-concept: http://en.wikipedia.org/wiki/Domain-driven_design)

A good post that wraps it together: http://blog.jonathanoliver.com/2010/09/cqrs-sagas-with-event-sourcing-part-ii-of-ii/

I'm getting to the question in a minute, but I think I have to try to summarize what I understand of it first (which might well be wrong, so please correct if that's the case) since this might well impact why I'm asking the question to begin with:

  1. The Saga pattern is a sort of broker that given an action (end-user, automated, etc. essentially anything that is going to change data) divides that action up in business activities and sends each of these activities as messages to a Message Bus which in turn sends it to the respective aggregate roots to be taken care of.
  2. These aggregate roots can operate completely autonomously (nice separation of concerns, great scalability, etc. )
  3. A Saga-instance itself doesn't contain any business logic, that is contained in the aggregate roots it sends activities to. The only 'logic' contained in the Saga is 'process'-logic, (often implemented as a Statemachine), which determines based on actions received (as well as follow-up events) what to do (i.e: what activities to send)
  4. The Saga-patterns implements a kind of distributed transaction pattern. I.e: when one of the aggregate roots (which again work autonomously, without knowing of eachothers existense) fails, the entire action might have to be rolled back.
  5. This is implemented by having all aggregate roots, upon completion of their activity report back to the Saga. (In case of success as well as error)
  6. In case all aggregate roots return a success, the internal statemachine if the Saga determines what to do next (or decides it's done)
  7. In case of failure, the Saga issues to all aggregate roots that took part in the last action a so called Compensation Action, i.e: an action to undo the last action each of the aggregate roots did.
  8. This might be simply doing a 'Minus 1 vote' if the action was "plus 1 vote' but it could be more complicated like restoring a blogpost to it's previous version.
  9. Event-sourcing (see the blogpost combining the two) aims to externalize saving the results of each of the activities that each of the aggregate roots undertake to a centralized Event Store (the changes are called 'events' in this context)
  10. This Event store is the 'single version of the truth' and can be use to replay the state of all entities simply by iterating the events stored (essentially like an event log)
  11. Combining the two (i.e: letting aggregate roots use Event-sourcing to outsource saving their changes before reporting back to the Saga) enables lots of nice possibilities, one of which concerns my question...

I felt I needed to get this off of my shoulder, since it's a lot to grasp in one go. Given this context/mindset (again, please correct if wrong)

the question: When an aggregate root receives a Compensate Action and if that aggregate root has outsourced it's state-changes using Event-sourcing, wouldn't the Compensate Action in all situations just be a delete of the last event in the Event Store for that given Aggregate Root? (Assuming the persist-implementation allows deletes)

That would make sense to me a lot (and would be another great benefit of this combination) but as I said I might be making these assumptions based on a incorrect/incomplete understanding of these concepts.

I hope this didn't get too long-winded.

Thanks.

share|improve this question

migrated from stackoverflow.com Jul 19 '12 at 2:01

This question came from our site for professional and enthusiast programmers.

add comment

2 Answers

up vote 3 down vote accepted

You shouldn't delete the events from your event store. These represent something that happened. If something happens now, then you should know it too, therefore add an event that will force your aggregate to go back to some previous state. That's a pity to delete information from your database.

think about the example of the cart from greg young and the removed items. May be tomorrow the information of compensating action might be of any value..

As for the saga, every thing is correct, as far as I know myself. You should think of the saga as of a state machine. It does only that.

It is a Command the saga is issuing to tell the aggregate to do something. Of this action there will be an event. This event might be the corrective action you need, or might need to be denormalised in a view so that some user will see it to decide what to do.

It depends on your business rules. Either, there is an easy fix : the aggregate root knows that in such case , you do that, or the choice is too complex to be done programmatically ( development cost are too high) and therefore, you might propose this to some user, who might choose between different action. Everything depend on the context of the compensating action. This is pure business rules. What should we do in this case or that case. This is something to ask your domain expert, and then choose with him, if it is better to develop an automatic solution or if the solution is to ask the user Ronald R., because he is the one to answer this question usually.

share|improve this answer
    
How would the aggregate know to which state to revert? Would it be allowed to query against the event-store or something? –  Geert-Jan Jul 19 '12 at 13:18
    
It should'nt revert but add another event. It is a Command the saga is issuing to tell the aggregate to do something. Of this action there will be an event. –  Arthis Jul 19 '12 at 13:39
    
Yeah I understand. "Revert" was probably ill-chosen. Consider the following: I might want to use Event Sourcing with Sagas for modeling, among other things, Document publishing / approval flows. What if an editor has send an ChangeBlogBody-action that is ultimately persisted as a BlogBodyChanged-event to the Event Store. Afterwards, for some reason, a Compensate Action is issued. How would the Aggregate know what compensate event to fire that results in the contents of the Blog Body as it was just before the ChangeBlogBody-action was issued? –  Geert-Jan Jul 19 '12 at 13:49
    
It depends on your business rules. Either, there is an easy fix : the aggregate root knows that in such case , you do that, or the choice is too complex to be done programmatically ( development cost are too high) and therefore, you might propose this to some user, who might choose between different action. –  Arthis Jul 19 '12 at 14:03
    
Everything depend on the context of the compensating action. This is pure business rules. What should we do in this case or that case. This is something to ask your domain expert, and then choose with him, if it is better to develop an automatic solution or if the solution is to ask the user Ronald R., because he is the one to answer this question usually. –  Arthis Jul 19 '12 at 14:11
show 3 more comments

For completeness I thought to include an relevant snippet from Martin Fowler about ways to revert state:

As well as events playing themselves forwards, it's also often useful for them to be able to reverse themselves.

Reversal is the most straightforward when the event is cast in the form of a difference. An example of this would be "add $10 to Martin's account" as opposed to "set Martin's account to $110". In the former case I can reverse by just subtracting $10, but in the latter case I don't have enough information to recreate the past value of the account.

If the input events don't follow the difference approach, then the event should ensure it stores everything needed for reversal during processing. You can do this by storing the previous values on any value that is changed, or by calculating and storing differences on the event.

From: http://martinfowler.com/eaaDev/EventSourcing.html

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.