Event Aggregator Error Handling With Rollback
Asked Answered
B

2

1

I've been studying a lot of the common ways that developers design/architect an application on domain driven design (Still trying to understand the concept as a whole). Some of the examples that I saw included the use of events via an event aggregator. I liked the concept because it truly keeps the different elements/domains of an application decoupled.

A concern that I have is: how do you rollback an operation in the case of an error?

For example:

Say I have an order application that has to save an order to the database and also save a copy of the order as a pdf to a CMS. The application fires an event that a new order has been created and the pdf service that subscribes to this event saves the pdf. Meanwhile when committing the order changes to the database an exception is thrown. The problem is that the pdf has been saved but their isn't a matching database record.

Should I cache the previously handled events and fire a new error event that looks to the cache for "undo" operations? Use something like the command pattern for this?

Or... is the event aggregator not a good pattern for this.

Edit

I'm starting to think that maybe events should be used for less "mission critical" items, such as emailing and logging.

My initial thought was to limit dependencies by using the event aggregator pattern.

Bearce answered 23/8, 2013 at 13:28 Comment(1)
Remember you can use in-memory events too; look up Udi Dahan Domain Events Salvation.Hunger
H
2

You want the event to be committed in the same transaction as the operation on your database.

In this particular scenario, you can push the event on a queue, which enlists in your transaction, so that the event will never go out unless the aggregate is persisted. This will make creating the PDF eventual consistent; if creating the PDF fails, you can fix the problem, and have it automatically retried.

Maybe you can get more inspiration in one of my previous posts on eventual consistent domain events with RavenDB and IronMQ.

Hunger answered 23/8, 2013 at 17:5 Comment(0)
L
2

Handling an event before it actually happened (committed) only works if the event handler participates in the transaction. Make the event handler transactional (for instance by storing the PDF in a database), or publish and handle events after the transaction committed.

Lilli answered 23/8, 2013 at 13:58 Comment(3)
I see the point about storing the PDF in the database but the second point with firing event after the record creation causes the same problem if the PDF creation fails.Bearce
@Bearce 2pc-commit if you need store the database and cms atomically, but I quite doubt the necessarity.Referee
@Bearce It's not the same problem. Failure while creating a PDF is an error, but creating a PDF for a non-existitent order creates an inconsistency. Event handlers can fail - fix the issue and handle the event again.Lilli
H
2

You want the event to be committed in the same transaction as the operation on your database.

In this particular scenario, you can push the event on a queue, which enlists in your transaction, so that the event will never go out unless the aggregate is persisted. This will make creating the PDF eventual consistent; if creating the PDF fails, you can fix the problem, and have it automatically retried.

Maybe you can get more inspiration in one of my previous posts on eventual consistent domain events with RavenDB and IronMQ.

Hunger answered 23/8, 2013 at 17:5 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.