Mise à jour perdueLa mise à jour perdue (en anglais lost update) est un type d'erreur qui peut apparaître en informatique lorsque plusieurs accès en écriture à une information partagée ont lieu en parallèle. Lorsque deux transactions modifient la même information, les modifications de la première peuvent être recouvertes immédiatement par celles de la seconde si aucune précaution n'est prise contre ce problème; on dit que les mises à jour effectuées par la première transaction ont été perdues. Ce problème peut se poser indépendamment de la forme que revêtent les informations partagées, qu'elles soient dans un fichier, dans une table de base de données ou en mémoire partagée entre plusieurs threads. Ce problème est également distinct de celui de la corruption des données qui peut intervenir en cas de mauvaise synchronisation des écritures, bien que les solutions aux deux problèmes utilisent souvent les mêmes mécanismes de base. Lectures et écritures sans interaction avec l'utilisateurExempleLe système informatique d'une salle de cinéma (où les places ne sont pas numérotées) stocke le nombre de billets déjà vendus pour la séance. 100 billets ont déjà été vendus, et la caisse no 2 est en train d'en vendre trois autres. Au même moment, la caisse no 1 enregistre le remboursement de cinq billets, qui doivent donc être soustraits du total. Le système de la caisse no 1 soustrait donc 5 au total du nombre de billets (100) et inscrit donc 95 en base de données. Immédiatement après, la caisse no 2 enregistre sa propre transaction et ajoute 3 au nombre de billets qu'elle-même a mémorisé, soit 103, et inscrit le résultat en base. La première mise à jour est donc perdue, et le résultat final est faux (103 au lieu de 98 places effectivement occupées).
Modifications atomiquesLa solution la plus simple au problème de la mise à jour perdue est de ne pas découper les opérations de lecture et d'écriture comme on l'a fait dans le pseudo-code des caisses de l'exemple précédent; à la place, on utilisera une opération atomique qui effectue la lecture et l'écriture, par exemple, dans une base de données SQL : UPDATE salles SET nb_places = nb_places + 5 WHERE numero_salle = 4; Verrouillage des donnéesLa solution des modifications atomiques ne s'applique pas lorsque le programme client d'un SGBD a le droit de prendre des décisions complexes en fonction des données qu'il lit avant d'effectuer ses écritures. Pour résoudre le problème de la mise à jour perdue dans ce contexte, il faut employer un mécanisme de verrouillage des données, qui interdira à plus d'un programme à la fois de modifier les données partagées. Les mécanismes primitifs de verrouillage pertinents sont les suivants :
Ces mécanismes sont fournis par tous les systèmes de données usuels :
Dans le cas des bases de données transactionnelles, le problème de la mise à jour perdue est plus souvent pris en charge directement par le SGBD, comme on le verra plus loin. Voici le déroulement des transactions de l'exemple ci-dessus, lorsqu'on utilise un verrou exclusif :
Niveaux d'isolation dans les bases de données SQLL'inconvénient principal de la méthode des verrous est qu'elle est discrétionnaire : elle repose sur le bon vouloir des transactions participantes pour acquérir et relâcher les verrous au bon moment, faute de quoi des mises à jour perdues, voire des problèmes plus graves comme la corruption des données, risquent de se produire. De plus, le verrou exclusif constitue un goulot d'étranglement potentiel, car il doit être détenu pendant le temps que durent les calculs de la transaction et les communications avec la base. Ce n'est sans doute pas un problème dans un cinéma, mais peut le devenir pour des systèmes plus complexes notamment s'ils sont répartis dans plusieurs sites à travers le monde. Le standard SQL92[1] définit une fonctionnalité connue sous le nom de niveaux d'isolation, qui consiste pour la base de données à traiter du côté serveur le problème de la mise à jour perdue. Pour l'algorithme des caisses de billetterie évoqué ci-dessus, un niveau d'isolation «lecture répétable» (repeatable read) suffit. Voici les commandes SQL nécessaires pour PostgreSQL, qui n'a pas de niveau d'isolation «lecture répétable» (on utilise donc «sérialisable» à la place, qui est plus fort) : BEGIN WORK SET TRANSACTION ISOLATION LEVEL SERIALIZABLE SELECT nb_places FROM salles WHERE no_salle = 4 -- Ici intervient le calcul du nombre de places restantes -- par la caisse UPDATE nb_places SET nb_places = 98 WHERE no_salle = 4 END WORK Le serveur de base de données peut choisir de traduire la commande Lectures et écritures en présence d'interactions avec l'utilisateurL'idée de répéter la transaction plusieurs fois n'est typiquement pas acceptable lorsqu'elle implique un utilisateur humain : en effet, celui-ci devrait recommencer tout son travail de saisie à chaque fois. Les solutions sont les suivantes :
Voir aussiNotes |
Portal di Ensiklopedia Dunia