PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Autorollback in postgres utilizzando PDO

Non è colpa di PDO, è inerente alla gestione delle transazioni di PostgreSQL. Vedi:

PostgreSQL non esegue il rollback della transazione, ma la imposta su uno stato interrotto in cui può solo eseguire il rollback e in cui tutte le istruzioni tranne ROLLBACK segnala un errore:

(Sono sorpreso di non trovare questo riferimento nella documentazione ufficiale; penso che dovrò scrivere una patch per migliorarlo.)

Così. Quando provi/cattura e inghiotti l'eccezione in PDO, stai intercettando un'eccezione sul lato PHP, ma non stai cambiando il fatto che la transazione PostgreSQL è in uno stato interrotto.

Se desideri essere in grado di eliminare le eccezioni e continuare a utilizzare la transazione, devi crea un SAVEPOINT prima di ogni affermazione che potrebbe fallire. Se fallisce, devi ROLLBACK TO SAVEPOINT ...; . Se riesce, puoi RELEASE SAVEPOINT ...; . Ciò impone un sovraccarico aggiuntivo al database per la gestione delle transazioni, aggiunge round trip e masterizza gli ID transazione più velocemente (il che significa che PostgreSQL deve eseguire più lavoro di pulizia in background).

In genere è preferibile invece progettare il tuo SQL in modo che non fallisca in circostanze normali. Ad esempio, puoi convalidare la maggior parte dei vincoli lato client, trattando i vincoli lato server come un secondo livello di garanzia e catturando la maggior parte degli errori lato client.

Laddove ciò non sia pratico, rendi la tua applicazione a tolleranza di errore, in modo che possa riprovare una transazione non riuscita. A volte ciò è comunque necessario, ad esempio, in genere non è possibile utilizzare i punti di salvataggio per eseguire il ripristino da deadlock, interruzioni di transazioni o errori di serializzazione. Può anche essere utile mantenere le transazioni soggette a errori il più brevi possibile, facendo solo il lavoro minimo richiesto, in modo da avere meno da tenere traccia e ripetere.

Quindi:ove possibile, invece di ingoiare un'eccezione, eseguire il codice del database soggetto a errori in un ciclo di tentativi. Assicurati che il tuo codice tenga un registro delle informazioni necessarie per ritentare l'intera transazione in caso di errore, non solo l'istruzione più recente.

Ricorda, qualsiasi la transazione può non riuscire:il DBA potrebbe riavviare il database per applicare una patch, il sistema potrebbe esaurire la RAM a causa di un processo cron incontrollato, ecc. Quindi le app tolleranti ai guasti sono comunque una buona progettazione.

Complimenti per almeno l'utilizzo delle eccezioni PDO e la gestione delle eccezioni:sei già molto più avanti della maggior parte degli sviluppatori.