Je travaille sur un programme qui émet du DDL. Je voudrais savoir si CREATE TABLE
un DDL similaire peut être restauré
- Postgres
- MySQL
- SQLite
- et al
Décrivez comment chaque base de données gère les transactions avec DDL.
Je travaille sur un programme qui émet du DDL. Je voudrais savoir si CREATE TABLE
un DDL similaire peut être restauré
Décrivez comment chaque base de données gère les transactions avec DDL.
Réponses:
http://wiki.postgresql.org/wiki/Transactional_DDL_in_PostgreSQL:_A_Competitive_Analysis fournit un aperçu de ce problème du point de vue de PostgreSQL.
Le DDL est-il transactionnel selon ce document?
SQLite semble également avoir un DDL transactionnel. J'ai pu faire ROLLBACK
une CREATE TABLE
déclaration dans SQLite. Sa CREATE TABLE
documentation ne mentionne aucun «piège» transactionnel spécial.
ALTER TABLE
instruction quelque peu limitée de SQLite peut également être annulée. Il n'est pas explicitement mentionné dans la documentation . Ce qui est mentionné, c'est comment effectuer des changements "avancés" dans une transaction.
PostgreSQL a un DDL transactionnel pour la plupart des objets de base de données (certainement les tables, les index, etc. mais pas les bases de données, les utilisateurs). Cependant, pratiquement n'importe quel DDL obtiendra un ACCESS EXCLUSIVE
verrou sur l'objet cible, le rendant complètement inaccessible jusqu'à ce que la transaction DDL se termine. De plus, toutes les situations ne sont pas tout à fait gérées - par exemple, si vous essayez de sélectionner dans une table foo
pendant qu'une autre transaction la supprime et crée une table de remplacement foo
, la transaction bloquée recevra finalement une erreur plutôt que de trouver la nouvelle foo
table. (Edit: cela a été corrigé dans ou avant PostgreSQL 9.3)
CREATE INDEX ... CONCURRENTLY
est exceptionnel, il utilise trois transactions pour ajouter un index à une table tout en autorisant les mises à jour simultanées, il ne peut donc pas être exécuté lui-même dans une transaction.
De plus, la commande de maintenance de la base de données VACUUM
ne peut pas être utilisée dans une transaction.
foo
pendant qu'une autre transaction est en train de la laisser tomber et de la recréer, alors je suis d'accord avec l'ancienne version ou l'erreur. Je ne suis pas d'accord avec la nouvelle version, car elle n'était pas encore validée, donc je ne dois pas la voir. Je suis d'accord avec une erreur, car dans l'accès transactionnel simultané, il faut être prêt à redémarrer les transactions de toute façon. Si les erreurs se produisent plus souvent que nécessaire, cela peut réduire les performances, mais cela reste correct.
Bien qu'il ne s'agisse pas à proprement parler d'une «restauration», dans Oracle, la commande FLASHBACK peut être utilisée pour annuler ces types de modifications, si la base de données a été configurée pour la prendre en charge.
On dirait que les autres réponses sont assez dépassées.
À partir de 2019:
START TRANSACTION ... COMMIT;
, vous ne pouvez toujours pas annuler les instructions DDL dans une transaction si celle-ci échoue dans la même transaction (voir note sous dev. mysql.com/doc/refman/8.0/en/… )
On ne peut pas faire avec MySQL il semble, très stupide, mais vrai ... (selon la réponse acceptée)
"L'instruction CREATE TABLE dans InnoDB est traitée comme une seule transaction. Cela signifie qu'un ROLLBACK de l'utilisateur n'annule pas les instructions CREATE TABLE que l'utilisateur a faites pendant cette transaction."
https://dev.mysql.com/doc/refman/5.7/en/implicit-commit.html
J'ai essayé de différentes manières et cela ne reviendra tout simplement pas.
Pour contourner le problème, il vous suffit de définir un indicateur d’échec et de faire «drop table tblname» si l’une des requêtes a échoué.