Pro e contro del controllo se esiste un valore per la colonna univoca o lasciare che db generi un errore univoco durante l'inserimento


8

Mentre scrivevo una domanda l'altro giorno mi è venuto in mente un pensiero che mi è rimasto impresso.

Cosa è preferibile, controllando prima se esiste un valore per una colonna univoca e quindi inserendo o inserendo e lasciando che db generi un errore di vincolo univoco? Importa anche?

Modifica: come suggerito di seguito in risposta che questo problema dipende dal database, sto aggiungendo il tag postgresql.

Risposte:


3

Non credo che la tua domanda sia davvero indipendente dal database. La risposta giusta potrebbe dipendere dai dettagli di implementazione, che possono variare da fornitore a fornitore e cambiare con la versione successiva. Vorrei testare in concomitanza prima di scegliere qualsiasi approccio su qualsiasi RDBMS.

In questo momento, su SQL Server 2008 R2, sto usando il seguente:

  1. Bassa concorrenza e basso numero di modifiche. Per salvare una singola riga, serializzo usando sp_getapplock e uso MERGE. Stress test in alta concorrenza per verificare che funzioni.

  2. Maggiore concorrenza e / o volume. Per evitare la concorrenza e aumentare le prestazioni, non salvo una riga alla volta. Accumulo modifiche sul mio server delle app e utilizzo i TVP per salvare i batch. Tuttavia, per evitare problemi relativi alla concorrenza, serializzo usando sp_getapplock prima del MERGE. Ancora una volta, stress test in alta concorrenza per verificare che funzioni.

Di conseguenza, abbiamo buone prestazioni e zero problemi relativi alla concorrenza nella produzione: nessun deadlock, nessuna violazione di vincoli PK / unique, ecc.


quindi vuoi dire che se i problemi di concorrenza sono gestiti bene, il controllo prima è una buona idea?
codecool

1
Sì, in genere evitare errori si comporta meglio che generare e rilevare eccezioni, ma è necessario confrontarli sulla propria piattaforma.
AK

7

Consentire al DB di generare un errore.

Il test prima non è sicuro per la concorrenza perché alla fine si otterrà una collisione perché 2 thread potrebbero passare "NON ESISTERE" ed entrambi proveranno a scrivere. Questo vale sia per le strategie di blocco "READ COMMITTED" sia per le strategie MVCC / Snapshot.

È possibile utilizzare i suggerimenti di blocco per forzare l'isolamento, ma si riducono le prestazioni.

Io chiamo questo il modello JFDI (link SO). Per "aggiorna se esiste", vedi qui: Hai bisogno di aiuto Risoluzione dei problemi Scenario deadlock di SQL Server 2005 . Questi sono SQL Server. MySQL ha INSERT IGNORE che lo gestisce con grazia. Non sono sicuro del resto


OKK. Non ci ho pensato! In caso di concorrenza, anche il controllo può fallire. :)
codecool


Penso che sia utile eseguire entrambi il controllo (e fallire con grazia) ma seguire l'adagio "fidati ma verifica" per catturare l'errore. La ragione? La gestione degli errori è costosa. Sto lavorando ad alcuni test oggi, in realtà, che dovrebbero rivelare se questo commento ha senso. Se questo commento scompare, conosci il risultato. :-)
Aaron Bertrand

Anche nel 2008 c'è MERGEche potrebbe aver risolto le osservazioni di Paul, ma non l'ho testato a tassi di tx elevati. Soprattutto perché devo ancora addestrare il mio cervello a capire quella sintassi.
Aaron Bertrand

1
Colpa mia. Ho fatto alcune osservazioni nei miei test oggi. Tieni presente che si tratta di test molto isolati senza concorrenza. Per inserti rettilinei, il controllo dapprima ed evitare l'errore è circa 10 volte più veloce rispetto al verificarsi dell'errore. Ma in altri casi in cui hai intenzione di fare una gestione degli errori più complessa (TRY / CATCH o IF @@ ERROR <> 0, con ROLLBACK o THROW, ecc.) È circa due volte più lenta se controlli prima. Ancora una volta sottolineerò che queste sono solo le mie osservazioni iniziali e ci sono molti fattori che possono influenzare l'impatto che può avere. Potrebbe passare un po 'di tempo prima che io possa scriverne un blog approfondito.
Aaron Bertrand
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.