Ich arbeite an einem Programm, das DDL ausgibt. Ich würde gerne wissen, ob CREATE TABLE
und ähnliche DDL zurückgesetzt werden können
- Postgres
- MySQL
- SQLite
- et al
Beschreiben Sie, wie jede Datenbank Transaktionen mit DDL verarbeitet.
Ich arbeite an einem Programm, das DDL ausgibt. Ich würde gerne wissen, ob CREATE TABLE
und ähnliche DDL zurückgesetzt werden können
Beschreiben Sie, wie jede Datenbank Transaktionen mit DDL verarbeitet.
Antworten:
http://wiki.postgresql.org/wiki/Transactional_DDL_in_PostgreSQL:_A_Competitive_Analysis bietet einen Überblick über dieses Problem aus Sicht von PostgreSQL.
Ist DDL gemäß diesem Dokument transaktional?
SQLite scheint auch Transaktions-DDL zu haben. Ich konnte ROLLBACK
eine CREATE TABLE
Anweisung in SQLite. In der CREATE TABLE
Dokumentation werden keine speziellen Transaktions-Fallstricke erwähnt.
ALTER TABLE
Anweisung von SQLite kann ebenfalls zurückgesetzt werden. Es wird in der Dokumentation nicht ausdrücklich erwähnt . Dort wird erwähnt, wie "erweiterte" Änderungen innerhalb einer Transaktion durchgeführt werden.
PostgreSQL verfügt über Transaktions-DDL für die meisten Datenbankobjekte (sicherlich Tabellen, Indizes usw., jedoch keine Datenbanken, Benutzer). Praktisch jede DDL erhält jedoch eine ACCESS EXCLUSIVE
Sperre für das Zielobjekt, sodass es bis zum Abschluss der DDL-Transaktion vollständig unzugänglich ist. Außerdem werden nicht alle Situationen ganz behandelt. Wenn Sie beispielsweise versuchen, aus einer Tabelle auszuwählen, foo
während eine andere Transaktion sie löscht und eine Ersatztabelle erstellt foo
, erhält die blockierte Transaktion schließlich einen Fehler, anstatt die neue foo
Tabelle zu finden. (Bearbeiten: Dies wurde in oder vor PostgreSQL 9.3 behoben.)
CREATE INDEX ... CONCURRENTLY
ist außergewöhnlich, es verwendet drei Transaktionen, um einer Tabelle einen Index hinzuzufügen und gleichzeitig gleichzeitige Aktualisierungen zuzulassen, sodass es selbst nicht in einer Transaktion ausgeführt werden kann.
Der Befehl zur Datenbankwartung VACUUM
kann auch nicht in einer Transaktion verwendet werden.
foo
während eine andere Transaktion gelöscht und neu erstellt wird, bin ich mit der alten Version oder dem Fehler einverstanden. Ich bin mit der neuen Version nicht einverstanden, da sie noch nicht festgeschrieben wurde, daher darf ich sie nicht sehen. Ich bin mit einem Fehler in Ordnung, da man beim gleichzeitigen Transaktionszugriff darauf vorbereitet sein muss, Transaktionen trotzdem neu zu starten. Wenn Fehler häufiger als nötig auftreten, kann dies die Leistung beeinträchtigen, ist aber dennoch korrekt.
Während es sich streng genommen nicht um ein "Rollback" handelt, kann in Oracle der Befehl FLASHBACK verwendet werden, um diese Art von Änderungen rückgängig zu machen, wenn die Datenbank so konfiguriert wurde, dass sie dies unterstützt.
Sieht aus wie die anderen Antworten ziemlich veraltet sind.
Stand 2019:
START TRANSACTION ... COMMIT;
. B. Sie können DDL-Anweisungen in einer Transaktion immer noch nicht zurücksetzen, wenn letztere in derselben Transaktion fehlschlägt (siehe Hinweis unter dev). mysql.com/doc/refman/8.0/en/… )
Kann nicht mit MySQL gemacht werden, es scheint sehr dumm, aber wahr ... (gemäß der akzeptierten Antwort)
"Die Anweisung CREATE TABLE in InnoDB wird als einzelne Transaktion verarbeitet. Dies bedeutet, dass ein ROLLBACK des Benutzers die Anweisungen CREATE TABLE, die der Benutzer während dieser Transaktion gemacht hat, nicht rückgängig macht."
https://dev.mysql.com/doc/refman/5.7/en/implicit-commit.html
Versuchte ein paar verschiedene Möglichkeiten und es wird einfach nicht zurückrollen ..
Um dieses Problem zu umgehen, setzen Sie einfach ein Fehlerflag und führen Sie "drop table tblname" aus, wenn eine der Abfragen fehlgeschlagen ist.