DDD / Aggregate Root / Versioning
Asked Answered
E

1

6

How do we usually deal with versioning of an aggregate root?

I was thinking along this line (I'm in a survey-design domain).

One way to have versioning is to have an explicit method to create a new version, based on the existing one. For example, Study (an aggregate root).

So initially we have an aggregate root, whose root-entity is Study with (business) key "ABC", version "1".

By invoking the method "newVersion()" on the Study, a copy of that Study and all the other entities that belong to the same aggregate root will be created.

So basically, versioning is done through creation a separate instance (of aggregate root). The ID is composite (business key + version).

How do we know if it's a branch? or is it just one version up? (1.1? or 2). I guess, this simple rule would work: if there's no further version associated, then it's "one version up" (2); if there's already another version, than it's a branch (1.1).

Another concern: noise.

But that means, we cannot work on / modify existing version. We'd have to create a newVersion everytime we want to make modifications to our object. Everytime??? Hmmm.... Doesn't sound right.

Or... we can make rule like this, based on a flag (active / not-active, or published / un-published). If the flag is "not-active", we can modify the AR directly, without creating a new version. If the flag is active we have to either: (a) set it to "not-active" first, and modify.... or (b) create a newVersion and work on the version (initially set to "not-active").

Any thoughts / experience you want to share on this matter?

Eichler answered 7/3, 2017 at 16:18 Comment(4)
Or we can simply forego numerical version, just let user decide the name of the version. The rate of change is not high anyway, so we can default to datestring, YYYYMMDD. Uniqueness checking can be done by traversal (traverse back and forth from the current AR to previous and next versions), and see if the version name has been used. It's more of a tagging than versioning.Eichler
If you consider event sourcing, you will get all changes recorded and probably you will not to have explicit versioning.Pepin
@cokordaraka Could you please elaborate on the versioning concept? Are you in the modeling realm or is there something you want to add to the concept of tactical ddd block namely aggregate. It is not clear . What is the versioning for?Continual
Hi Sergiy: #42653688Eichler
S
8

I think you will find things a bit confusing in researching this question, because there are two very different concepts at play:

  • Versioning as a concurrency control mechanism to support optimistic concurrency
  • Versioning as an explicit domain concept

Versioning to support Optimistic Concurrency

Optimistic concurrency is when two simultaneous transactions are allowed to start, but if they both try and modify the same data item, only the first one is permitted to proceed. See Concurrency Control for an overview of different locking strategies.

In summary, you leave versioning up to the persistence technology, because the purpose of the version is to detect simultaneous writes to the persistence layer.

When using this pattern, it's common to not even keep copies of old versions, however it's certainly possible to do so as an audit trail/change log.

Versioning as an explicit domain concept

Based on your question, and the need to support potential branching strategies, it sounds like versioning is an explicit domain concept in your domain - i.e. the concept of a "Version" is something that your domain experts talk about, and working with versions is an important part of the ubiquitous language.

However, you raise a few different concepts which indicate that the domain needs further exploration:

  • Version branching
  • User-defined version naming/tagging (but still connected to a 'chain' of versions)
  • Explicit version changes (user requested) vs implicit version changes (automatic on every change)
    • If I understand your intent correctly, with explicit versioning, the current 'active'/'live'/'tip' version is mutable and can be modified without tracking the change, until the user 'commits' it - it becomes immutable, and a new 'live' version that is mutable is created.

Some other concepts that may come up if you explore this version:

  • Branch merging (once you have split two branches, what happens if you want to bring them back together?)
  • Rolling back - if you have an old version, do you support 'undoing' one or more changes?

Given the above, you may also find some insights from the way that version control systems work both centralised (e.g. subversion) and distributed (e.g. git and mercurial), as they present an active working model of version tracking with a mixture of mutable and immutable elements.

The open questions here suggest to me that you need to explore this in more detail with your domain experts. With DDD sometimes it's easy to get lost in what you can do, but I strongly encourage you to try and understand what you need to do.

How do your users/domain experts think about the world? What kind of operations do they want to be able to do? What is the purpose of these operations towards their initial goal? Your aim is to distill the answers to these questions into a model that effectively encapsulates the processes they work with.

Edit to Consider Modelling

Based on your comment - my first response would be to challenge the interpretation of the word 'version' when thinking about the modified questionnaire. In fact, I'd be tempted to challenge the modelling of the template/survey relationship. Consider a possible set of entities:

  • Template

    • Defines the set of questions in the questionnaire
    • Supports operations:
      • StartSurvey
      • Various operations to modify the questions and options in the template etc.
  • Survey

    • Rather than referencing a 'live' template, the survey would own it's own questionnaire
    • When you call Template.StartSurvey it returns a Survey that is prefilled with the list of questions from the template
    • A survey also supports modifying the questions - but this doesn't change the template it was created from
    • Unlike a template, a survey also maintains a list of recorded answers, and offers operations to set the answers
    • It probably also includes a lifecycle state wherein in some states answering questions is permitted, but once 'submitted' you can't modify the answers (just guessing on this one).

In this world, the survey is 'stamped out' from the template, but then lives an independent life. You can modify the questionnaire in the survey all you like, and it won't effect the template.

The trade-off here is that if you do modify the template, none of the surveys that have already been created from it would get updated - but it sounds like that might be safer for you anyway?

You could also support operations to convert a survey back into a template so that if you like the look of a modified survey, you could 'templatize' it so it could be used for future surveys.

Strigose answered 9/3, 2017 at 19:9 Comment(3)
Hi Chris, thanks for your comprehensive answer. The versioning in my case is more of domain concept (I believe). It comes from situations where in the middle of survey, one is allowed to update the questionnaire (another version). It shouldn't happen in ideal situation, but it does happen. Now, the survey is based on a template (so you don't want that decision to switch to another version of questionnaire in one survey affects other surveys based on the same template). I'm still racking my brain to come up with proper model in the light of new knowledge on sampling techniques.Eichler
Updated answer to consider some modelling scenarios that might help.Strigose
Hi Chris, thanks for the answer. I was also thinking along that line. I guess in this brave new world of microservice we really shouldn't be worried about copying stuffs. And about modified template, probably with ES, we can devise a mechanism for updating "unfulfilled survey / survey waiting in line" to be notified, and get its copy updated (completely replaced).Eichler

© 2022 - 2024 — McMap. All rights reserved.