2008-09-02 11 views
12

Come gestite le eccezioni del database nell'applicazione?
Si sta provando a convalidare i dati prima di trasmetterli al DB o semplicemente fare affidamento sulla logica di convalida dello schema DB?
Provate a recuperare da qualche tipo di errore DB (ad es. Timeout)?Migliori pratiche di gestione delle eccezioni del database

Ecco alcuni approcci:

  1. dati Convalida prima di passarlo al DB
  2. convalida sinistra a DB e gestire le eccezioni DB correttamente
  3. Convalida su entrambi i lati
  4. Convalida alcuni vincoli evidenti nel mondo degli affari logica e sinistra convalida complessa a DB

Che approccio usi? Perché?

Aggiornamenti:

Sono contento di vedere crescere la discussione.
Proviamo a riassumere le risposte della comunità.

Suggerimenti:

  • Convalida su entrambi i lati
  • Controlla i vincoli della logica di business su lato client, e tanto DB fanno integrità controlla from hamishmcn
  • Controllare in anticipo per evitare fastidio DB from ajmastrean
  • check-in anticipato a migliorare l'esperienza utente from Will
  • Mantieni il codice di interazione DB in posizione su semplificare lo sviluppo from hamishmcn
  • Object-Relational Mapping (NHibernate, LINQ, ecc) può aiutare a trattare con vincoli from ajmastrean
  • validazione lato client è necessario per motivi di sicurezza from Seb Nilsson

Avete qualcos'altro dire? Questo è convertito in domanda specifica di convalida. Ci manca il nucleo, ovvero "Buone pratiche degli errori relativi al database" quali sono da gestire e quali da ingannare?

risposta

1

In generale, provo a convalidare i dati il ​​più presto possibile dopo che è stato inserito. Questo è così che posso dare messaggi utili all'utente prima che dopo aver cliccato su "Invia" o l'equivalente.
Nel momento in cui si tratta di effettuare il db call, sono fiducioso che i dati che sto passando dovrebbero essere abbastanza buoni.
Provo a mantenere le chiamate in db nell'unico file (o gruppo di file) che condividono i metodi di supporto per rendere il più semplice possibile il programmatore (io o chiunque altro aggiunge chiamate) a scrivere in un registro dettagli sull'eccezione e quali parametri sono stati passati in ecc.

2

Provo a convalidare su entrambi i lati. 1 regola che seguo sempre non è mai un input di fiducia da parte dell'utente. Seguendo questo alla sua conclusione, di solito avrò qualche convalida del front end sul modulo/pagina web che non permetterà nemmeno l'invio con dati formati in modo improprio.Questo è uno strumento contundente: ciò significa che è possibile controllare/analizzare il valore per assicurarsi che un campo data contenga una data. Da lì, di solito permetto alla mia logica aziendale di verificare se l'inserimento dei dati ha senso nel contesto di come è stato inviato. Ad esempio, la data inviata rientra nell'intervallo previsto? Il valore della valuta inviato rientra nell'intervallo previsto? Infine, sul lato server, i vincoli Foreign Key e gli indici possono rilevare eventuali errori che sfuggono, il che farà apparire un'eccezione DB come ultima risorsa, che può essere gestita dal codice dell'app. Io uso questo metodo perché filtra tutti gli errori possibili prima che la chiamata DB venga invocata.

3

Si desidera ridurre i viaggi non necessari nel DB, pertanto eseguire la convalida all'interno dell'applicazione è una buona pratica. Inoltre, ti consente di gestire gli errori dei dati in cui è più facile eseguire il ripristino da: vicino all'interfaccia utente (sia nel controller o all'interno del livello dell'interfaccia utente per le app più semplici) in cui vengono immessi i dati.

Ci sono alcuni errori di dati che non è possibile controllare a livello di programmazione, tuttavia. Ad esempio, non è possibile convalidare dati sull'esistenza di dati correlati senza round verso il db. Errori di dati come questi dovrebbero essere convalidati dal database attraverso l'uso di relazioni, trigger, ecc.

Dove si gestiscono gli errori restituiti dalle chiamate al database è interessante. Potresti gestirli a livello di dati, livello di business logic o livello dell'interfaccia utente. La migliore pratica in questo caso è quella di lasciare che quegli errori si presentino nell'ultimo momento responsabile prima di gestirli.

Ad esempio, se si dispone di un'applicazione Web ASP.NET MVC, si dispone di tre livelli (dal basso verso l'alto): database, controller e interfaccia utente (modello, controller e vista). A tutti gli errori lanciati dal livello dati dovrebbe essere permesso di entrare nel tuo controller. A questo livello l'applicazione "sa" ciò che l'utente sta tentando di fare e può informare correttamente l'utente sull'errore, suggerendo diversi modi per gestirlo. Tentare di recuperare da questi errori all'interno del livello dati rende molto più difficile sapere cosa sta succedendo all'interno del controller. E, naturalmente, inserire la logica di business all'interno dell'interfaccia utente non è considerata una best practice.

TL; DR: convalida ovunque, gestisce gli errori di convalida nell'ultimo momento responsabile.

0

Il tipo di app che stavo scrivendo (da allora ho spostato i lavori) erano app fat-client in-house.
Vorrei provare a mantenere la logica di business nel client e fare più convalida meccanica sul db (cioè convalida che riguardava solo la capacità della procedura di eseguire, al contrario della convalida di livello superiore).
In breve, convalidare dove è possibile e provare a mantenere insieme i tipi di convalida correlati.

+0

[@hamishmcn] (http://stackoverflow.com/questions/39371/database-exception-handling-best-practices#39406). buon punto, una ragione per avere la convalida nel livello della logica aziendale è creare un'interfaccia utente user friendly. Ma avere queste convalide in più punti rompe il principio SECCO. Come riesci a mantenere sincronizzate le convalide di DB e client side? – aku

5

@aku: ASCIUGARE è bello, ma non è sempre possibile. La convalida è una di quelle posizioni, poiché avrai tre luoghi completamente diversi e non correlati in cui la convalida non solo è possibile ma assolutamente necessaria: all'interno dell'interfaccia utente, all'interno della logica aziendale e all'interno del database.

Pensa a un'applicazione web. Si desidera ridurre i viaggi sul server, quindi includere la convalida javascript dell'inserimento dei dati del client. Ma non ci si può fidare di ciò che l'utente inserisce, quindi è necessario eseguire la convalida all'interno della propria logica aziendale prima di toccare il database. E il database deve avere la propria validazione per prevenire la corruzione dei dati.

Non esiste un modo pulito per unificare questi tre diversi tipi di convalida all'interno di un singolo componente.

ci sono alcuni tentativi compiuti per unificare le responsabilità trasversali come la convalida entro iniettori politici come il gruppo P & P Policy Injection Application Block combinato con la loro Validation Application Block, ma questi si basano ancora il codice.Se la convalida non è in codice, è necessario mantenere la logica parallela separatamente ...

2

Uno strumento ORM (object-relational mapping), come NHibernate (o, meglio ancora, ActiveRecord), può aiutare a evitare molto di convalida consentendo al modello di dati di essere integrato direttamente nel codice come una classe C# corretta. Puoi anche evitare viaggi nel database, grazie a modelli di caching e validazione integrati nel framework.

4

C'è un motivo killer da convalidare sia sul lato client che sul lato database, e cioè sicurezza. Soprattutto quando inizi a utilizzare elementi AJAX, URL hackerabili e altre cose che rendono il tuo sito (in questo caso) più amichevole per gli hacker degli utenti e.

Convalidare sul client per fornire un'esperienza fluida per comunicare tempestivamente all'utente il proprio input. Convalidare anche nel database, (o in business logic, se questo è considerato un gateway totalmente sicuro per il database) per la sicurezza del database.