Sto lavorando a un programma che emette DDL. Vorrei sapere se è CREATE TABLE
possibile eseguire il rollback di un DDL simile
- Postgres
- MySQL
- SQLite
- et al
Descrivi come ogni database gestisce le transazioni con DDL.
Sto lavorando a un programma che emette DDL. Vorrei sapere se è CREATE TABLE
possibile eseguire il rollback di un DDL simile
Descrivi come ogni database gestisce le transazioni con DDL.
Risposte:
http://wiki.postgresql.org/wiki/Transactional_DDL_in_PostgreSQL:_A_Competitive_Analysis fornisce una panoramica di questo problema dal punto di vista di PostgreSQL.
DDL è transazionale secondo questo documento?
Anche SQLite sembra avere un DDL transazionale. Sono stato in grado di ROLLBACK
una CREATE TABLE
dichiarazione in SQLite. La sua CREATE TABLE
documentazione non menziona alcun "trucco" transazionale speciale.
ALTER TABLE
È anche possibile annullare l'istruzione un po 'limitata di SQLite. Non è esplicitamente menzionato nella documentazione . Ciò che è menzionato c'è come eseguire modifiche "avanzate" all'interno di una transazione.
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 ACCESS EXCLUSIVE
blocco sull'oggetto di destinazione, rendendolo completamente inaccessibile fino al termine della transazione DDL. Inoltre, non tutte le situazioni sono gestite del tutto, ad esempio, se provi a selezionare dalla tabella foo
mentre un'altra transazione la rilascia e crea una tabella sostitutiva foo
, la transazione bloccata riceverà finalmente un errore anziché trovare la nuova foo
tabella. (Modifica: questo problema è stato risolto in o prima di PostgreSQL 9.3)
CREATE INDEX ... CONCURRENTLY
è eccezionale, utilizza tre transazioni per aggiungere un indice a una tabella consentendo al contempo aggiornamenti simultanei, quindi non può essere eseguito da solo in una transazione.
Inoltre, il comando di manutenzione del database VACUUM
non può essere utilizzato in una transazione.
foo
mentre un'altra transazione viene rilasciata e ricreata, allora ottengo un OK con la vecchia versione o errore. Non sto bene con la nuova versione, perché non è stata ancora impegnata, quindi non devo vederla. Sto bene con un errore, perché in un accesso transazionale simultaneo bisogna essere preparati a riavviare comunque le transazioni. Se gli errori si verificano più spesso del necessario, potrebbe ridurre le prestazioni, ma è comunque corretto.
Sebbene non sia strettamente parlando un "rollback", in Oracle il comando FLASHBACK può essere utilizzato per annullare questi tipi di modifiche, se il database è stato configurato per supportarlo.
Sembra che le altre risposte siano piuttosto obsolete.
A partire dal 2019:
START TRANSACTION ... COMMIT;
quindi non è ancora possibile ripristinare le istruzioni DDL in una transazione se quest'ultima nella stessa transazione fallisce (vedere la nota sotto dev. mysql.com/doc/refman/8.0/en/… )
Non può essere fatto con MySQL sembra, molto stupido, ma vero ... (come da risposta accettata)
"L'istruzione CREATE TABLE in InnoDB viene elaborata come una singola transazione. Ciò significa che un ROLLBACK da parte dell'utente non annulla le istruzioni CREATE TABLE effettuate dall'utente durante quella transazione."
https://dev.mysql.com/doc/refman/5.7/en/implicit-commit.html
Ho provato diversi modi e semplicemente non tornerà indietro.
La soluzione consiste nell'impostare semplicemente un flag di errore ed eseguire "drop table tblname" se una delle query fallisce.