Uniqueness validation when using CQRS and Event sourcing

后端 未结 3 1529
渐次进展
渐次进展 2021-01-31 10:42

I\'m trying to implement my own CQRS infrastructure with Event Sourcing to learn it better. As a sample project I\'m implementing a blog engine, I know it might not be a perfect

相关标签:
3条回答
  • 2021-01-31 10:59

    I've read through the various answers on this and the related question.

    The decision comes down to correctness. If you can be forgiving and accept imperfect behavior for some degree of a operation, your problem is much simpler to solve, especially under weak consistency guarantees.

    However, if you want consistency you should use a persistence service that has strong consistency guarantees.

    For example, the command that creates the short URL will validate that the read store does not contain such a short URL already and we will only commit our event, if we can commit the changes to our read store first.

    If we can commit our changes to our read store, we have not violated any uniqueness constraint (assuming that your read store enforces such a constraint) and we can then proceed.

    However, since we have two transactions not necessarily on the same database we might fail after the first commit. This is OK because the operation will as a whole will also fail. The read store will reflect an inconsistent state for some time but as soon as we repair the aggregate the read store will back in a consistent state.

    As a maintenance procedure we could periodically repair aggregates that have been subject to potential errors. And you can do this by introducing an error flag that is only cleared if both transactions commit successfully.

    There was an example wherein a bank would allow a user to overdraw their account because they have surcharges for that to compensate. This raises questions because it would seem sloppy to solve a problem like that, lazy even. Some call it smart. I don't know what to think. The bank probably has enough money to cover it, so they might as well ignore it but that's no how the world currently works. Anyway, I digress.

    From a correctness stance, our read store has a strong consistency guarantee and we would write our projection in such a way that we cannot commit a transaction to the read store if the balance is put in the negative. As such the worst thing that can happen is that a charge is deducted from the read store but the operation was never fully committed in the event store. The user would see money missing from their account until the maintenance procedure noticed the error flag and healed the account. This I think is a working compromise.

    0 讨论(0)
  • 2021-01-31 11:01

    It depends what 'the business' wants to happen. If you want the client (creator of the commands) to be responsible for choosing a short URL, it should have a read store that it verifies the uniqueness of it from. When the user types in a short URL, the view should check that the short URL is unique and present a validation error if it is not. Whenever a post is saved, an event will publish the updated info (including the short URL) which keeps the read store in sync.

    0 讨论(0)
  • 2021-01-31 11:04

    I would go for an application service that is just responsible for generating unique ShortURL's. You can use a transactional DB to implement this behaviour. Typically this service would be used by the command handling part of the BlogPost aggregate. If there is a duplicate ShortURL, you can fire a DuplicateUrlErrorEvent. You can pre-catch this in the UI (but never 100%) by creating a thin query-model using the same data-source, so you can query whether a shortified URL is unique before submitting the post (as described by @RyanR's answer).

    0 讨论(0)
提交回复
热议问题