Gestione della logica aziendale / Condizioni di convalida della convalida

0

Sto lavorando a un'applicazione web Training Enrollment con le seguenti funzionalità (semplificate):

  1. Manutenzione (aggiunta, modifica, disattivazione) dei corsi di formazione
  2. Registrazione degli studenti
  3. Iscrizione degli studenti a corsi di formazione attivi

Ho impiegato Onion Architecture. Tutta la mia logica di business / validazione è nel livello di dominio e il livello di accesso ai dati è costituito da componenti ADO.NET e stored procedure (nessuna logica di business qualunque). Il problema è che poiché la logica di business / validazione è nel dominio, potrebbe esserci una condizione di competizione nei seguenti scenari:

Scenario 1

  1. L'allenamento A consente solo un massimo di 50 studenti

  2. La formazione A ha attualmente 49 studenti iscritti

  3. Nell'applicazione web, due utenti tentano di iscriversi contemporaneamente. A questo punto sono stati generati due thread da due le richieste simultanee all'applicazione Web sono in grado di interrogare 49 utenti, quindi entrambe le convalide hanno successo nel livello Dominio e in entrambi gli utenti possono iscriversi.

Scenario 2

  1. L'allenamento A è creato

  2. Lo studente A sta tentando di iscriversi alla formazione A

  3. Mentre lo studente A sta tentando di iscriversi alla formazione A, un amministratore della formazione decide di disattivare la formazione A. Una condizione di competizione si verifica quando nel livello Dominio, quando accade quanto segue: Nel thread 1 di L'utente 1, che convalida se l'allenamento A è attivo, ha successo (restituisce vero) e allo stesso tempo;

    1. Nel thread 2, il thread su cui viene disattivato Training A convalida che non ci sono ancora iscrizioni; così che entrambi le convalide hanno esito positivo.

Una soluzione ovvia è aggiungere la logica di business (controllare il conteggio delle iscrizioni, verificare se un allenamento è attivo) nelle mie stored procedure, ma sono riluttante a farlo mentre interrompe il progetto.

La mia logica di convalida ha un singolo punto di ingresso e posso aggiungere un blocco in modo tale che la logica di convalida diventi una sezione critica in modo che una sola operazione (convalida e persistenza DB) avvenga contemporaneamente, ma ciò riduce la concorrenza.

Qualunque approccio alternativo o come è stato risolto nei sistemi su cui hai lavorato?

    
posta rro 14.04.2015 - 04:09
fonte

2 risposte

1

Vorrei andare con il blocco e assicurarmi che la convalida della registrazione sia a thread singolo.

Questo è simile a qualsiasi altro scenario simile in cui un numero potenzialmente elevato di utenti sta tentando di proteggere una risorsa scarsa: registrandosi per classe / formazione, prenotando un posto su un aereo, acquistando in anticipo un biglietto per il cinema per l'apertura giorno di un blockbuster, ecc. In altre parole, per garantire che una risorsa scarsa venga assegnata correttamente in queste situazioni, hai per usare la concorrenza.

La maggior parte delle volte, gli utenti andranno bene con il minimo tempo aggiuntivo e la bassa probabilità di errore ("riprova"). Questi sono i tipi di processi che comportano l'addebito di carte di credito, la comunicazione con sistemi esterni, ecc. E siamo abituati agli inconvenienti.

Non sono sicuro di dove sia esattamente la logica di convalida, ma normalmente viene eseguita nel database come stored procedure. Se non altro, una procedura che blocca la tabella di registrazione per la modifica, inserisce una riga e restituisce l'ID del record o non riesce. A parte la logica di blocco nel tuo stile SQL, dovrebbero essere due o tre istruzioni.

    
risposta data 14.04.2015 - 04:29
fonte
0

Un approccio alternativo, che può o non può essere appropriato per la tua situazione, sarebbe quello di implementare una coda e avere un thread o un processo di lavoro che elabora gli elementi nella coda. Ci sarà sempre una sola istanza del lavoratore. Il lavoratore elabora le richieste in un ordine FIFO.

In questo modo si eliminano le condizioni della gara: se due utenti si iscrivono entrambi per l'ultimo slot contemporaneamente, solo uno di loro lo otterrà, e si può inviare una notifica all'altro che la loro richiesta è stata negata. Ci sono vari modi per farlo, uno sarebbe avere utenti reindirizzati a una pagina che dice "richiesta in sospeso" che viene aggiornata una volta che la richiesta è stata elaborata dal thread di lavoro.

    
risposta data 15.04.2015 - 00:46
fonte