Suppongo che desideri ignorare il secondo aggiornamento. Esistono altri scenari (ad esempio, anziché inserire una nuova riga, aggiornare determinati campi della riga esistente), ma deduco che stai cercando qualcosa chiamato AddOrIgnore
anziché AddOrUpdate
.
Qui ci sono alcune strade possibili, alcune migliori di altre.
Blocco a livello di applicazione .
Questo sembra il più semplice da implementare, ma non è la soluzione migliore. Ci sarà una quantità minima di tempo tra controllare per l'esistenza e salvare l'oggetto. In questo intervallo di tempo, è possibile inserire una riga e si otterrebbero comunque dati duplicati.
Le condizioni di gara sono notoriamente difficili da debugare, quindi suggerisco di evitarle a tutti i costi.
Blocco a livello di database .
Il blocco del database ti dà la possibilità di prevenire le condizioni della gara.
Tuttavia, se ti aspetti un sacco di accesso simultaneo a quella tabella (per oggetti diversi, i cui stati non colliderebbero mai), allora questo potrebbe diventare un collo di bottiglia per le prestazioni.
Non sono sicuro che il blocco possa essere garantito per tutti gli aggiornamenti della tabella. Perché se non può, allora corri il rischio che altre parti si dimentichino di implementare il comportamento di blocco.
Ripulitura dopo il fatto .
Questo è più facile da implementare ma potrebbe finire per causare un po 'più di lavoro. Questo si applica solo nei casi in cui l'aggiornamento dello stato non restituisce un valore e non ti interessa avvisare l'utente / l'applicazione che è stato trovato un duplicato (ma che invece continua a funzionare normalmente).
Il vantaggio è che non è necessario bloccare il comportamento e puoi semplicemente pulire i dati in seguito (rimuovendo eventuali duplicati). A seconda di evitare che i duplicati siano critici per l'azienda; potresti programmarlo come un lavoro. Oppure puoi creare un'attività per controllarla (preferibilmente in un thread separato che ignora e dimentica).
Lo svantaggio è che potresti finire per dover annullare il lavoro che hai appena fatto, che è un lavoro extra. Se il tuo server verrà premuto per le prestazioni, più lavoro sarà sempre una brutta cosa. La domanda qui è la frequenza con cui ti aspetti di incappare in collisioni e quanto verrai premuto per le prestazioni sul server.
Un secondo vantaggio è che la richiesta originale non viene rallentata eseguendo un controllo aggiuntivo e delegando invece il comportamento di controllo a un thread secondario / attività / processo pianificato.
Questo dipende molto dal tuo ambiente.
Se stai creando un servizio molto utilizzato in cui le voci duplicate sono rare e nient'altro che un difetto estetico, il blocco creerebbe un collo di bottiglia per tutti. L'aggiunta e la pulizia, tuttavia, bloccherà solo quelle richieste che accadono per essere eseguite in una collisione rara.
Se stai creando un servizio in cui le voci duplicate possono causare problemi importanti, dovresti concentrarti sul blocco anziché sulla pulizia dopo il fatto.
Se stai creando un servizio in cui le voci duplicate sono un'occorrenza comune, il comportamento di pulizia causa troppo lavoro extra troppo spesso. Se i duplicati non causano problemi, puoi pulirlo in un lavoro pianificato. Se i duplicati causano problemi, devi concentrarti sul comportamento di blocco.