I have been reading Alistair Cockburn's article on Hexagonal Architecture. One question that occurs to me, is how to handle situations where there are database concurrency issues.
An obvious example is a situation where an entity is retrieved from the repository, has an integer attribute incremented, and then is saved back to the repository.
In a web context, its possible that two requests could attempt to increment at the same time, with familiar incorrect results.
An obvious solution would be to do the incrementing in an SQL query (or ORM equivalent). A django ORM example:
Comments.objects.filter(pk=comment.pk).update(vote=F('vote') + 1)
However, hexagonal architecture seems to rule this out, since it would place business logic in the repository.
A similar problem could take place when different requests attempt to modify different fields. For example:
- In request A, a comment is retrieved from the repo to edit its content.
- In request B, the same comment is retrieved to increment its vote tally.
- In request B, the incremented comment is saved to the repo.
- In request A, the edited comment is saved to the repo (including the old vote tally value), overwriting the vote tally increment made by in request A.
The following django ORM example shows one way that this can be solved:
But its not obvious how to do this in a "hexagonal" way, where the business logic is meant to take place in "pure" code, unadulterated by database concerns.
Is there a common solution to this sort of problem?