Ho letto l'articolo di Alistair Cockburn su Hexagonal Architecture . Una domanda che mi viene in mente è come gestire le situazioni in cui esistono problemi di concorrenza del database.
Un esempio ovvio è una situazione in cui un'entità viene recuperata dal repository, ha un attributo intero incrementato e quindi viene salvato nel repository.
In un contesto web, è possibile che due richieste possano tentare di incrementare allo stesso tempo, con risultati familiari non corretti.
Una soluzione ovvia sarebbe fare l'incremento in una query SQL (o equivalente ORM). Un esempio di ORG django:
Comments.objects.filter(pk=comment.pk).update(vote=F('vote') + 1)
Tuttavia, l'architettura esagonale sembra escluderla, poiché posizionerebbe la logica aziendale nel repository.
Un problema simile potrebbe verificarsi quando richieste diverse tentano di modificare campi diversi. Ad esempio:
- Nella richiesta A, un commento viene recuperato dal repository per modificare il suo contenuto.
- Nella richiesta B, lo stesso commento viene recuperato per incrementare il numero di voti.
- Nella richiesta B, il commento incrementato viene salvato nel repository.
- Nella richiesta A, il commento modificato viene salvato sul repository (incluso il vecchio valore di votazione), sovrascrivendo l'incremento del conteggio del voto effettuato nella richiesta A.
Il seguente esempio di ORG django mostra un modo in cui questo può essere risolto:
comment.save(update_fields=["content"])
Ma non è ovvio come farlo in un modo "esagonale", in cui la logica di business è intesa per avere luogo in un codice "puro", non alterato dai problemi del database.
Esiste una soluzione comune a questo tipo di problema?