Pracuję nad programem, który wystawia DDL. Chciałbym wiedzieć, czy CREATE TABLE
i podobne DDL można przywrócić
- Postgres
- MySQL
- SQLite
- et al
Opisz, jak każda baza danych obsługuje transakcje z DDL.
Pracuję nad programem, który wystawia DDL. Chciałbym wiedzieć, czy CREATE TABLE
i podobne DDL można przywrócić
Opisz, jak każda baza danych obsługuje transakcje z DDL.
Odpowiedzi:
http://wiki.postgresql.org/wiki/Transactional_DDL_in_PostgreSQL:_A_Competitive_Analysis zawiera przegląd tego problemu z perspektywy PostgreSQL.
Czy DDL ma charakter transakcyjny zgodnie z tym dokumentem?
Wydaje się, że SQLite ma również transakcyjny DDL. Udało mi ROLLBACK
się CREATE TABLE
wypowiedzieć w SQLite. Jego CREATE TABLE
dokumentacja nie wspomina o żadnych specjalnych „pułapkach” transakcyjnych.
ALTER TABLE
instrukcję SQLite można również wycofać. Nie jest to wyraźnie wymienione w dokumentacji . Wspomniano tam o tym, jak dokonywać „zaawansowanych” zmian wewnątrz transakcji.
PostgreSQL ma transakcyjny DDL dla większości obiektów bazy danych (z pewnością tabele, indeksy itp., Ale nie bazy danych, użytkownicy). Jednak praktycznie każdy DDL zostanie ACCESS EXCLUSIVE
zablokowany na obiekcie docelowym, co sprawi, że będzie on całkowicie niedostępny do czasu zakończenia transakcji DDL. Ponadto nie wszystkie sytuacje są w pełni obsługiwane - na przykład, jeśli spróbujesz wybrać z tabeli, foo
podczas gdy inna transakcja porzuca ją i tworzy tabelę zastępczą foo
, zablokowana transakcja ostatecznie otrzyma błąd, zamiast znaleźć nową foo
tabelę. (Edycja: zostało to naprawione w PostgreSQL 9.3 lub wcześniej)
CREATE INDEX ... CONCURRENTLY
jest wyjątkowy, wykorzystuje trzy transakcje, aby dodać indeks do tabeli, jednocześnie zezwalając na jednoczesne aktualizacje, więc nie można go samodzielnie wykonać w transakcji.
W VACUUM
transakcji nie można również użyć komendy konserwacji bazy danych .
foo
podczas gdy inna transakcja jest porzucana i odtwarzana, wtedy mam OK ze starą wersją lub błędem. Nie jest mi dobrze z nową wersją, ponieważ nie została jeszcze zatwierdzona, więc nie mogę jej zobaczyć. Nic mi nie jest z błędem, ponieważ przy jednoczesnym dostępie transakcyjnym i tak trzeba być przygotowanym na ponowne uruchomienie transakcji. Jeśli błędy występują częściej niż to konieczne, może to zmniejszyć wydajność, ale nadal jest poprawne.
Chociaż nie jest to ściśle mówiąc „wycofanie”, w Oracle polecenie FLASHBACK może być używane do cofania tego typu zmian, jeśli baza danych została skonfigurowana do jej obsługi.
Wygląda na to, że inne odpowiedzi są dość nieaktualne.
Od 2019 r .:
START TRANSACTION ... COMMIT;
. Nadal nie można wycofać instrukcji DDL w transakcji, jeśli ostatnia w tej samej transakcji się nie powiedzie (patrz uwaga pod dev. mysql.com/doc/refman/8.0/en/... )
Wydaje się, że nie można tego zrobić z MySQL , bardzo głupie, ale prawdziwe ... (zgodnie z zaakceptowaną odpowiedzią)
„Instrukcja CREATE TABLE w InnoDB jest przetwarzana jako pojedyncza transakcja. Oznacza to, że ROLLBACK użytkownika nie cofa instrukcji CREATE TABLE wykonanych przez użytkownika podczas tej transakcji.”
https://dev.mysql.com/doc/refman/5.7/en/implicit-commit.html
Wypróbowano na kilka różnych sposobów i po prostu się nie wycofa.
Aby obejść ten problem, wystarczy ustawić flagę błędu i wykonać „drop table tblname”, jeśli jedno z zapytań zakończyło się niepowodzeniem.