Architettura esagonale e concorrenza di database

0

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:

  1. Nella richiesta A, un commento viene recuperato dal repository per modificare il suo contenuto.
  2. Nella richiesta B, lo stesso commento viene recuperato per incrementare il numero di voti.
  3. Nella richiesta B, il commento incrementato viene salvato nel repository.
  4. 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?

    
posta samfrances 22.04.2018 - 18:08
fonte

1 risposta

3

L'idea centrale dell'architettura esagonale è che la logica aziendale definisce varie interfacce e i sistemi esterni sono adattati a questa interfaccia.

Ad esempio, se la logica aziendale vuole essere in grado di aggiornare solo il corpo di un commento, quindi aggiungere tali metodi all'interfaccia di persistenza. Il codice del database che implementa questa interfaccia può quindi utilizzare SQL appropriato (ad esempio, aggiorna solo il campo del corpo del commento, non il campo del voto del commento).

Se la logica aziendale desidera eseguire una serie di modifiche a livello di transazione, scrivere questa scheda di database in un modo che supporti le transazioni.

L'architettura esagonale non esclude l'utilizzo di SQL o di varie funzioni ORM. Tuttavia, questo non dovrebbe accadere all'interno della logica del core business, ma dovrebbe essere collocato nell'adattatore del database. Non è possibile delegare tutti i problemi di concorrenza all'adattatore del database, ma potrebbe essere una preoccupazione principale dell'applicazione. Tuttavia, la logica aziendale può definire astrazioni convenienti e di alto livello implementate in un adattatore.

Si noti che a volte può essere ragionevole non andare completamente esagonale. In un'app CRUD, l'utilizzo di un layer di database (non dell'adattatore!) O di SQL raw può essere più comodo, e la creazione di adattatori complicherebbe inutilmente le cose.

    
risposta data 22.04.2018 - 19:17
fonte