Super-héros sans tête
[10 minutes]
Les usines GARVEL construisent des figurines de super-héros à partir des données présentes dans la base de données PostgreSQL de l'entreprise. Un gros problème est survenu le mois dernier, lorsque l'usine en charge d'une nouvelle figurine, Superchild, a livré un million d'exemplaires sans tête. À l'analyse de la base il a en effet été observé que la base contenait un tuple "Superchild" dans la table Personnage, et cinq tuples associés dans la table Membre, deux pour les bras, deux pour les jambes et un pour le torse, mais aucun pour la tête.
Le service qui a opéré la saisie du nouveau personnage assure, sans ambiguïté possible, que la tête a pourtant été saisie dans la base. En revanche, l'enquête montre des instabilités de son réseau à cette période.
L'extrait du modèle UML utile au problème est proposé ci-après, ainsi que le code SQL exécuté via le client psql
lors de l'insertion de la nouvelle figurine.
\set AUTOCOMMIT on
INSERT INTO Personnage (designation, prix, identite_secrete, genre) VALUES ('Superchild','12','Jordy','superhéros') ;
INSERT INTO Membre (propriétaire, nom, couleur) VALUES ('Superchild','bras droit','bleu') ;
INSERT INTO Membre (propriétaire, nom, couleur) VALUES ('Superchild','bras gauche','bleu') ;
INSERT INTO Membre (propriétaire, nom, couleur) VALUES ('Superchild','jambe gauche','bleu') ;
INSERT INTO Membre (propriétaire, nom, couleur) VALUES ('Superchild','jambe droite','bleu') ;
INSERT INTO Membre (propriétaire, nom, couleur) VALUES ('Superchild','torse','rouge') ;
INSERT INTO Membre (propriétaire, nom, couleur) VALUES ('Superchild','tete','rose') ;
Question
Expliquer la nature du problème qui est probablement survenu. Proposer une solution générale pour que le problème ne se renouvelle pas, en expliquant pourquoi.
Soyez concis et précis : La bonne mobilisation des concepts du domaine et la clarté de la rédaction seront appréciées.
Solution
Explication
Le script est en mode AUTOCOMMIT ce qui signifie que chaque instruction est isolée dans une transaction propre, un COMMIT implicite étant exécuté après chaque INSERT (voir ci-après).
Une défaillance système (probablement une coupure réseau) est survenue juste avant le dernier INSERT, ce qui a empêché son exécution. Les six premiers INSERT ont donc été exécutés, mais pas le septième (celui qui concerne la tête).
INSERT INTO Personnage (designation, prix, identite_secrete, genre) VALUES ('Superchild','12','Jordy','superhéros') ;
COMMIT ;
INSERT INTO Membre (propriétaire, nom, couleur) VALUES ('Superchild','tete','rose') ;
COMMIT ;
INSERT INTO Membre (propriétaire, nom, couleur) VALUES ('Superchild','bras droit','bleu') ;
COMMIT ;
INSERT INTO Membre (propriétaire, nom, couleur) VALUES ('Superchild','bras gauche','bleu') ;
COMMIT ;
INSERT INTO Membre (propriétaire, nom, couleur) VALUES ('Superchild','torse','rouge') ;
COMMIT ;
INSERT INTO Membre (propriétaire, nom, couleur) VALUES ('Superchild','jambe gauche','bleu') ;
COMMIT ;
INSERT INTO Membre (propriétaire, nom, couleur) VALUES ('Superchild','jambe droite','bleu') ;
COMMIT ;
Question
Illustrer la solution proposée en corrigeant le code SQL de l'insertion de "Superchild".
Solution
AUTOCOMMIT désactivé, BEGIN implicite
Pour gérer ce problème il faut encapsuler les sept INSERT dans une unique transaction, celle-ci en assure alors l'atomicité : il ne sera plus possible à une partie seulement des INSERT d'être exécutée.
\set AUTOCOMMIT off
INSERT INTO Personnage (designation, prix, identite_secrete, genre) VALUES ('Superchild','12','Jordy','superhéros') ;
INSERT INTO Membre (propriétaire, nom, couleur) VALUES ('Superchild','tete','rose') ;
INSERT INTO Membre (propriétaire, nom, couleur) VALUES ('Superchild','bras droit','bleu') ;
INSERT INTO Membre (propriétaire, nom, couleur) VALUES ('Superchild','bras gauche','bleu') ;
INSERT INTO Membre (propriétaire, nom, couleur) VALUES ('Superchild','torse','rouge') ;
INSERT INTO Membre (propriétaire, nom, couleur) VALUES ('Superchild','jambe gauche','bleu') ;
INSERT INTO Membre (propriétaire, nom, couleur) VALUES ('Superchild','jambe droite','bleu') ;
COMMIT ;
Solution
AUTOCOMMIT activé, BEGIN explicite
BEGIN TRANSACTION ;
INSERT INTO Personnage (designation, prix, identite_secrete, genre) VALUES ('Superchild','12','Jordy','superhéros') ;
INSERT INTO Membre (propriétaire, nom, couleur) VALUES ('Superchild','tete','rose') ;
INSERT INTO Membre (propriétaire, nom, couleur) VALUES ('Superchild','bras droit','bleu') ;
INSERT INTO Membre (propriétaire, nom, couleur) VALUES ('Superchild','bras gauche','bleu') ;
INSERT INTO Membre (propriétaire, nom, couleur) VALUES ('Superchild','torse','rouge') ;
INSERT INTO Membre (propriétaire, nom, couleur) VALUES ('Superchild','jambe gauche','bleu') ;
INSERT INTO Membre (propriétaire, nom, couleur) VALUES ('Superchild','jambe droite','bleu') ;
COMMIT TRANSACTION ;