2010-10-18 11 views
18

Quando si lavora con transazioni di database, quali sono le possibili condizioni (se presenti) che causerebbero il fallimento dell'affermazione finale COMMIT in una transazione, presumendo che tutte le istruzioni all'interno della transazione siano già state eseguite senza problemi?Una dichiarazione COMMIT (in SQL) può mai fallire? Come?


Per esempio ... Diciamo che avete un po 'two-phase o three-phase commit protocol dove si fa un mucchio di dichiarazioni, quindi attendere qualche processo maestro per dirvi quando è ok per commettere finalmente la transazione:

-- <initial handshaking stuff> 
START TRANSACTION; 
-- <Execute a bunch of SQL statements> 
-- <Inform master of readiness to commit> 
-- <Time passes... background transactions happening while we wait> 
-- <Receive approval to commit from master (finally!)> 
COMMIT; 

Se il codice raggiunge la dichiarazione COMMIT finale e lo invia al DBMS, è possibile ottenere un errore (problema di unicità, database completo, ecc.) In tale istruzione? Quali errori? Perché? Come appaiono? Varia a seconda di quale DBMS viene eseguito?

+0

Se questo è compito, taggalo come tale. –

+3

@Bob Jarvis: Wow. Grazie per avermi fatto sentire molto più giovane! – Russ

+4

compiti a casa non è una funzione dell'età. :-) –

risposta

9

È possibile che alcuni motori di database rimandino il controllo dei vincoli di indice UNIQUE fino a COMMIT. Ovviamente se il vincolo non è vero al momento del commit, fallirà.

+0

Davvero? Questo è ciò di cui avevo paura. Sai di alcuni motori in particolare che fanno questo? – Russ

+3

È una nuova funzionalità di PostgreSQL 9.0. http://wiki.postgresql.org/wiki/What%27s_new_in_PostgreSQL_9.0#DEFERRABLE_UNIQUE_CONSTRAINTS –

+2

Oracle può rinviare il controllo dei vincoli FK, http://infolab.stanford.edu/~ullman/fcdb/oracle/or-triggers.html –

4

Sicuro.

In un ambiente multiutente, COMMIT potrebbe non riuscire a causa di modifiche da parte di altri utenti (ad esempio, il COMMIT violerebbe un vincolo referenziale quando applicato al database corrente ...).

Thomas

4

Certo, ci potrebbe essere un certo numero di questioni. L'atto di impegnare, in sé e per sé, deve fare un ingresso definitivo e definitivo per indicare che l'operazione è stata commessa. Se la registrazione non riesce, la transazione non può essere eseguita.

Come indicato da Ignacio, è possibile eseguire il controllo di restrizione dei vincoli (questa potrebbe essere una qualsiasi forma di vincolo, non solo un vincolo univoco, a seconda del motore DBMS).

Specifico del server SQL: flushing I dati FILESTREAM possono essere posticipati fino al commit time. Questo potrebbe fallire.

4

Un elemento molto semplice e spesso trascurato: guasto hardware. Il commit può fallire se il server sottostante muore. Potrebbe trattarsi di disco, cpu, memoria o anche della rete.

La transazione potrebbe non riuscire se non riceve l'approvazione dal master (per un numero qualsiasi di ragioni).

15

COMMIT potrebbe non funzionare. Potresti aver avuto risorse sufficienti per registrare tutte le modifiche che desideri apportare, ma mancano risorse per implementare effettivamente le modifiche.

E questo senza considerare altri motivi potrebbe non riuscire:

  1. Il cambiamento stesso potrebbe non andare bene i vincoli del database.

  2. La perdita di potenza arresta le cose dal completamento.

  3. Il livello della concorrenza di selezione richiesta potrebbe non consentire un aggiornamento (cursori che aggiornano una tabella modificata, ad esempio).

  4. Il commit potrebbe scadere o essere su una connessione che scade a causa di problemi di fame.

  5. La connessione di rete tra il client e il database potrebbe andare persa.

E tutti gli altri motivi "semplici" che non sono in cima alla mia testa.

1

Indipendentemente dal modo in cui un sistema può essere progettato, ci sarà la possibilità che un commit entri in una situazione in cui è impossibile sapere se ci sia riuscito o meno. In alcuni casi potrebbe non avere importanza (ad esempio, se un disco rigido contenente il database si trasforma in una pila di scorie, potrebbe essere impossibile stabilire se il commit è riuscito o meno prima che ciò si verificasse, ma non avrebbe avuto importanza); in altri casi, tuttavia, questo potrebbe essere un problema. Soprattutto con i sistemi di database distribuiti, se un errore di connessione si verifica nel momento giusto durante un commit, sarà possibile per entrambe le parti essere certi se l'altra parte si aspetta un commit o un rollback.

4

Se si utilizza il commit a due fasi, quindi no. Tutto ciò che potrebbe andare storto viene fatto nella fase di preparazione.

Potrebbe esserci ancora un'interruzione di rete, meno energia, raggi cosmici, ecc. Durante il commit, ma anche così, le transazioni saranno state scritte nella memoria permanente, e se un commit è stato attivato, i processi di recupero dovrebbero portarli attraverso.

Speriamo.

Problemi correlati