Pracuję nad programem, który wystawia DDL. Chciałbym wiedzieć, czy CREATE TABLEi 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 TABLEi 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 ROLLBACKsię CREATE TABLEwypowiedzieć w SQLite. Jego CREATE TABLEdokumentacja nie wspomina o żadnych specjalnych „pułapkach” transakcyjnych.
ALTER TABLEinstrukcję 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 EXCLUSIVEzablokowany 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, foopodczas gdy inna transakcja porzuca ją i tworzy tabelę zastępczą foo, zablokowana transakcja ostatecznie otrzyma błąd, zamiast znaleźć nową footabelę. (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 VACUUMtransakcji nie można również użyć komendy konserwacji bazy danych .
foopodczas 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.