2011-01-14 14 views

risposta

107

http://wiki.postgresql.org/wiki/Transactional_DDL_in_PostgreSQL:_A_Competitive_Analysis fornisce una panoramica di questo problema dalla prospettiva di PostgreSQL.

DDL transazionale secondo questo documento?

  • PostgreSQL - sì
  • MySQL - no; DDL causa un commit implicito
  • Oracle Database 11g versione 2 e successive - per impostazione predefinita, no, ma esiste un'alternativa denominata ridefinizione basata su edizione
  • Versioni precedenti di Oracle - no; DDL causa un implicito commettere
  • SQL Server - sì
  • Sybase Adaptive Server - sì
  • DB2 - sì
  • Informix - sì
  • Firebird (Interbase) - sì

SQLite appare anche avere DDL transazionale pure. Sono stato in grado di scrivere ROLLBACK a CREATE TABLE in SQLite. La sua documentazione CREATE TABLE non menziona alcun "trucchi" transazionali speciali.

+5

Tuttavia, il driver Python predefinito per sqlite impedisce l'SQL transazionale. http://bugs.python.org/issue10740 – joeforker

+0

Quindi la risposta è "Sì, possono essere ripristinati, a meno che non si utilizzi MySQL o versioni precedenti di Oracle." – rjmunro

+0

No, ci sono altri database SQL oltre a quelli elencati. – joeforker

3

Anche se non si tratta di un "rollback" in senso stretto, in Oracle il comando FLASHBACK può essere utilizzato per annullare questi tipi di modifiche, se il database è stato configurato per supportarlo.

19

PostgreSQL ha DDL transazionale per la maggior parte degli oggetti di database (certamente tabelle, indici ecc. Ma non database, utenti). Tuttavia, praticamente qualsiasi DDL otterrà un blocco ACCESS EXCLUSIVE sull'oggetto di destinazione, rendendolo completamente inaccessibile fino al termine della transazione DDL. Inoltre, non tutte le situazioni sono abbastanza gestite, ad esempio, se provi a selezionare dalla tabella foo mentre un'altra transazione la fa cadere e creando una tabella di sostituzione foo, la transazione bloccata riceverà infine un errore piuttosto che trovare la nuova tabella foo. (Modifica: è stato corretto in o prima di PostgreSQL 9.3)

è eccezionale, utilizza tre transazioni per aggiungere un indice a una tabella pur consentendo aggiornamenti simultanei, quindi non può essere eseguito in una transazione.

Inoltre, il comando di manutenzione del database VACUUM non può essere utilizzato in una transazione.

+0

+1 per le informazioni di 'ACCESS EXCLUSIVE'! –

+0

Direi che se provo per selezionare dalla tabella 'pippo' mentre un'altra transazione sta cadendo e ricrearla, quindi io un OK w con la vecchia versione o errore. Non sono d'accordo con la nuova versione, perché non è stata ancora eseguita, quindi non devo vederla. Sto bene con un errore, perché nell'accesso transazionale concorrente bisogna essere pronti a riavviare comunque le transazioni. Se gli errori si verificano più spesso del necessario, potrebbe ridurre le prestazioni, ma è ancora corretto. –

+0

@JanHudec: non vedrete una versione senza commit della nuova tabella, solo il risultato dell'intera transazione che lo ha abbandonato/ricreato. cioè una transazione che cade, ricrea e ripopola una tabella è effettivamente atomica rispetto ad altri processi che selezionano da quella tabella. (ma tutto verrà bloccato non appena provano a leggere lo schema della tabella) – araqnid

0

non può essere fatto con MySQL a quanto pare, molto stupido ..

"L'istruzione CREATE TABLE in InnoDB viene elaborata come una singola transazione.Ciò significa che un ROLLBACK da parte dell'utente non annulla CREATE TABLE all'utente fatta durante la transazione."

https://dev.mysql.com/doc/refman/5.7/en/implicit-commit.html

provato un paio di modi diversi e semplicemente non rotolare indietro ..

È sufficiente impostare un flag di errore e fare "drop table tblname" se una delle query non è riuscita ..