Domanda

Un membro del team ha riscontrato un problema con un vecchio sistema interno in cui un utente facendo doppio clic su un collegamento in una pagina Web può causare l'invio di due richieste dal browser con conseguente inserimento di due database dello stesso record in condizioni di gara; l'ultimo da eseguire non riesce con una violazione della chiave primaria. Diverse soluzioni e hack sono stati proposti e discussi:

  1. Usa Javascript sulla pagina web per mitigare il secondo clic disabilitando il collegamento al primo clic. Questo è un modo rapido e semplice per ridurre le occorrenze del problema, ma non eliminarlo del tutto.

  2. Termina l'esecuzione della richiesta sul lato sever in una transazione. Ciò è stato ritenuto troppo costoso per un'operazione a causa del carico del server e dei livelli di blocco nella tabella in questione.

  3. Cattura l'eccezione della chiave primaria generata dall'inserimento non riuscito, identificandola come tale e mangiandola. Ciò ha gli svantaggi di (a) blocco del fornitore, dover conoscere le sfumature delle eccezioni specifiche del database e (b) potenzialmente non registrare / gestire errori legittimi del database.

  4. Un'estensione di # 3 tentando di aggiornare il record se l'inserimento non riesce e controllando il risultato dell'aggiornamento per assicurarsi che restituisca 1 record interessato.

Le altre opzioni non sono state considerate? Ci sono pro e contro delle opzioni presentate che sono state trascurate? Qual è il minore di tutti i mali?

È stato utile?

Soluzione

È necessario implementare il modello di token Synchronizer.

Come funziona: un valore (il token) viene generato sul server per ogni richiesta. Lo stesso token deve quindi essere incluso nell'invio del modulo. Alla ricezione della richiesta vengono confrontati il ??token server e il token client e, se sono uguali, è possibile continuare ad aggiungere il record. Il token lato server viene quindi rigenerato, quindi le richieste successive contenenti il ??vecchio token non riusciranno.

Esiste una spiegazione più approfondita a metà questa pagina .

Non sono sicuro della tecnologia che stai utilizzando, ma Struts fornisce supporto a livello di framework per questo modello. Vedi esempio qui

Altri suggerimenti

Metti un identificatore univoco sulla pagina in un campo nascosto. Accetta solo una risposta con un determinato identificatore univoco.

Sembra che tu stia abusando di una richiesta GET per modificare lo stato del server (anche se questo non è necessariamente il caso). Anche se potrebbe non essere appropriato per la tua situazione, dovresti dichiarare che dovresti considerare di convertire il link in un modulo POST.

Sembra che tu abbia già risposto alla tua domanda lì; # 1 sembra essere l'unica opzione praticabile.

Altrimenti, dovresti davvero fare tutti e tre i passaggi: l'integrità dei dati dovrebbe essere gestita a livello di database, ma controlli extra (come la transazione esplicita) nel codice per evitare viaggi di andata e ritorno nel database potrebbero essere buoni per le prestazioni.

RIF È necessario implementare il modello di token Synchronizer.

Questo è per Javascript / HTML non JAVA

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top