Décision : quel niveau d'isolation ?
Le niveau d'isolation des transactions détermine l'équilibre entre concurrence et cohérence. Une isolation plus élevée signifie moins d'anomalies mais davantage de verrous/conflits et de nouvelles tentatives. Cet arbre vous aide à choisir entre Read Committed, Repeatable Read/Snapshot et Serializable selon les anomalies de lecture (dirty, non-repeatable, phantom) que vous pouvez tolérer.
Pouvez-vous tolérer les lectures sales (dirty reads) ?
Commencez par l'anomalie la plus élémentaire : une transaction doit-elle pouvoir lire des données qui ne sont pas encore validées (et peuvent être annulées) ? Presque aucune application sérieuse ne le souhaite ; dans la plupart des moteurs modernes, le comportement par défaut empêche déjà les lectures sales. On ne l'assouplit que pour des comptages approximatifs/analytiques et une vitesse maximale.
- Non, je dois lire uniquement des données validées
- Oui, une lecture approximative suffit (rare)
Devez-vous voir le même résultat en relisant au sein de la même transaction ?
Les lectures sales étant exclues, la question suivante : si vous lisez deux fois la même ligne dans une transaction, est-ce un problème de voir une valeur différente parce que quelqu'un a validé entre-temps (non-repeatable read), ou de voir apparaître de nouvelles lignes (phantom) ? Une logique exigeant la cohérence d'un rapport/calcul nécessite généralement un snapshot cohérent.
- Non, chaque instruction peut voir les dernières données validées
- Oui, un snapshot cohérent est nécessaire pour toute la transaction
Les transactions concurrentes doivent-elles être logiquement entièrement ordonnées ?
Vous voulez des lectures cohérentes ; est-ce suffisant, ou les transactions concurrentes doivent-elles produire un résultat comme si elles s'étaient exécutées une par une, en séquence (serializable) ? Si vous pouvez tolérer des anomalies subtiles comme le write skew (par ex. deux transactions lisant des lignes différentes et écrivant de façon à s'invalider mutuellement), Snapshot suffit ; sinon, une sérialisation complète est requise.
- Non, un snapshot cohérent suffit
- Oui, aucune anomalie de concurrence n'est acceptable
Recommandation : Read Uncommitted (cas particuliers uniquement)
L'isolation la plus faible ; elle autorise les lectures sales. Elle lit presque sans attendre les verrous, mais vous pouvez voir des données susceptibles d'être annulées. Déconseillée pour les applications généralistes.
Recommandation : Read Committed (OLTP par défaut)
Chaque instruction voit les dernières données validées à cet instant ; les lectures sales sont empêchées. C'est le niveau par défaut dans la plupart des moteurs et il offre le meilleur équilibre concurrence/cohérence pour les charges OLTP typiques.
Recommandation : Repeatable Read / Snapshot (lectures cohérentes)
La transaction travaille sur un snapshot cohérent figé à son début (ou à sa première lecture) ; les lectures ne changent pas pendant la transaction. Avec MVCC, les lecteurs ne bloquent pas les écrivains et les écrivains ne bloquent pas les lecteurs.
Recommandation : Serializable (isolation complète)
L'isolation la plus élevée : les transactions concurrentes produisent un résultat comme si elles avaient été exécutées en série (une par une, en séquence). Elle empêche toutes les anomalies de lecture et le write skew ; le prix est davantage de conflits et la nécessité de nouvelles tentatives.