1

I'm working on a HR application that has employee management and access control.
We decided to go with these bounded contexts:

  • Employee management: manage employees information, like name, contract, birthdate etc
  • Access control: manage whether an employee can get into the facility, in which case we upload his or her fingerprint to fingerprint scanners. (fingerprint should be uploaded beforehand)
  • Presence and absence: calendar (hours of work of each employee), based on information from timecloks, we get to calculate presence, absence, how many times employee got into the facility etc.

the boundaries between these bounded contexts are clear and easily seen by the specific language of each of these contexts.
The problem at hand is, we have a UI page that holds employee information, this same page contains both information related to employee management and also information related to access control (example: identifier of this employee in the fingerprint scanners which is an integer).

When the user edits all this data, he saves it at once with save button, this is supposed to be single transaction (the save), but it involves two savings of two aggregates in two bounded contexts.
Currently, aggregates across all these bounded contexts are saved in one database but we like to keep the possibility of making them in separate schemas in the future.

How to handle this situation to insure that if saving in one database wasn't done properly for some reason, than the saving in the other database is not going to be saved as well.

Also I thought about changing the way we do our UI, but this situation is almost frequent where one UI can hold information of multiple contexts, and saving info on that page will include updates on those contexts as well at once.

Any suggestions will be much appreciated.

asked Jan 9, 2023 at 15:51
1
  • Saga Pattern is usually how to handle this issue. Simply said, it is a manually implement transaction that rollbacks changes if one of the parts fails. Yes, it is additinal complexity, but that is price for domain separation. Commented Jan 9, 2023 at 19:56

2 Answers 2

1

How to handle this situation to insure that if saving in one database wasn't done properly for some reason, than the saving in the other database is not going to be saved as well.

I would recommend against artificially putting this into one transaction if there is no business reason for it. Since these are different bounded contexts, there will most likely nothing really "bad" happen when savings to one of the contexts will succeed and another one will fail. Just think of your UI as a binding bracket over three invidual UIs with individual Save buttons.

Of course, the Save operation inside your UI should

  • iterate over all the three partial Saves

  • collect failure state and failure messages for each individual step,

  • tell the user precisely which of the steps succeeded and which failed.

If it makes sense to stop further savings when one of the previous saves failed depends heavily on the case, but usually there should be no need to undo a successful partial save.

There are some options you can consider to make this more user-friendly:

  • You may visualize which parameters / attributes are already saved in the DB and which are pending. Depending on the application and how it is used, this may be negligible, or crucial, or only convenient.

  • You may run a validation of the data inside the UI before you try to save it, and force the user to correct anything which would let the save operation fail. This does not give a 100% chance against failure during the real save operation, but it can sort out most domain reasons, leaving only technical failures or failures by unexpected concurrent access.

Finally, if you really need to implement a transaction over multiple bounded contexts, which may be persisted within different storage systems, look into techniques like Two-phase commit or the Saga pattern. Here is also a Stackoverflow Q&A comparing the two.

answered Jan 9, 2023 at 18:47
2

I mean it doesn't sound overly critical, I would just allow the UI to show the partial failure.

However, the way to do it is to allow undo's of the various actions. This means you need to store a history of each object, perhaps use the Event Store pattern?

You can then add the various updates in a "Pending" way and then send a "Complete" message to mark them and finished if everything worked.

Obviously you have "what if the transaction completion fails for some contexts!" problems, which you can solve with a clean up job running on a schedule to roll back bad changes delete old "pending" updates etc

answered Jan 9, 2023 at 16:29

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.