Sérialisation et isolation des transactions

Cette page décrit les conflits, les sérialisations et l'isolation des données transactionnelles. Pour obtenir des exemples de code de transaction, consultez plutôt Transactions et écritures par lot.

Transactions et conflits de données

Pour qu'une transaction aboutisse, les documents récupérés par ses opérations de lecture ne doivent pas être modifiés par des opérations extérieures à la transaction. Si une autre opération tente de modifier l'un de ces documents, l'opération engendre un conflit de données avec la transaction.

Litige de données
Lorsque deux opérations ou plus entrent en concurrence pour contrôler le même document. Par exemple, une transaction peut nécessiter la cohérence du document, tandis qu'une opération simultanée tente de mettre à jour les valeurs de ce document.

Firestore résout les conflits de données en retardant ou en échec l'une des opérations. Les bibliothèques clientes Firestore relancent automatiquement les transactions qui échouent en raison de conflits de données. Après un nombre limité de tentatives, l'opération de transaction échoue et renvoie un message d'erreur:

ABORTED: Too much contention on these documents. Please try again.

Lors du choix de l'opération à échouer ou retarder, le comportement dépend du type de bibliothèque cliente.

  • Les SDK pour mobile/Web utilisent des contrôles de simultanéité optimistes.

  • Les bibliothèques clientes du serveur utilisent des contrôles de simultanéité pessimistes.

Contention des données dans les SDK pour mobile/Web

Les SDK pour mobile/Web (plates-formes Apple, Android, Web, C++) utilisent des contrôles de simultanéité optimistes pour résoudre les conflits de données.

Contrôles de simultanéité optimistes
Partir de l'hypothèse que les conflits de données sont peu probables ou qu'ils ne sont pas efficaces pour conserver les verrous de base de données. Les transactions optimistes n'utilisent pas de verrous de base de données pour empêcher d'autres opérations de modifier des données.

Les SDK pour mobile/Web utilisent des contrôles de simultanéité optimistes, car ils peuvent fonctionner dans des environnements avec une latence élevée et une connexion réseau peu fiable. Le verrouillage de documents dans un environnement à latence élevée entraîne trop de conflits de données.

Dans les SDK pour mobile/Web, une transaction assure le suivi de tous les documents que vous lisez au sein de la transaction. La transaction termine ses opérations d'écriture uniquement si aucun de ces documents n'a été modifié pendant l'exécution de la transaction. Si un document a changé, le gestionnaire de transactions relance la transaction. Si la transaction ne peut pas générer un résultat propre après plusieurs tentatives, la transaction échoue en raison d'un conflit de données.

Contention des données dans les bibliothèques clientes du serveur

Les bibliothèques clientes du serveur (C#, Go, Java, Node.js, PHP, Python et Ruby) utilisent des contrôles de simultanéité pessimistes pour résoudre les conflits de données.

Contrôles de simultanéité pessimistes
Partir de l'hypothèse que les conflits de données sont probables. Les transactions pessimistes utilisent des verrous de base de données pour empêcher d'autres opérations de modifier des données.

Les bibliothèques clientes de serveur utilisent des contrôles de simultanéité pessimistes, car elles supposent une faible latence et une connexion fiable à la base de données.

Dans les bibliothèques clientes du serveur, les transactions placent des verrous sur les documents qu'elles lisent. Le verrouillage d'une transaction sur un document empêche d'autres transactions, écritures par lot et écritures non transactionnelles de modifier ce document. Une transaction libère le document qui est verrouillé au moment du commit. Il bloque également ses verrous en cas d'expiration du délai ou de défaillance pour une raison quelconque.

Lorsqu'une transaction verrouille un document, d'autres opérations d'écriture doivent attendre que la transaction libère son verrou. Les transactions acquièrent leurs verrous dans l'ordre chronologique.

Isolation sérialisable

Les conflits de données entre les transactions sont étroitement liés aux niveaux d'isolation de la base de données. Le niveau d'isolation de base de données décrit la capacité du système à gérer les conflits entre les opérations simultanées. Les conflits proviennent des exigences de base de données suivantes:

  • Les transactions nécessitent des données précises et cohérentes.
  • Pour utiliser efficacement les ressources, les bases de données exécutent les opérations simultanément.

Dans les systèmes à faible niveau d'isolation, une opération de lecture au sein d'une transaction peut lire des données inexactes à partir de modifications non validées dans une opération simultanée.

L'isolation sérialisable définit le niveau d'isolation le plus élevé. L'isolation sérialisée signifie que:

  • Vous pouvez supposer que la base de données exécute les transactions en série.
  • Les transactions ne sont pas affectées par les modifications non validées dans les opérations simultanées.

Cette garantie doit être maintenue même lorsque la base de données exécute plusieurs transactions en parallèle. La base de données doit mettre en œuvre des contrôles de simultanéité pour résoudre les conflits qui pourraient rompre cette garantie.

Firestore garantit l'isolation sérialisable des transactions. Les transactions dans Firestore sont sérialisées et isolées par date de commit.

Isolation sérialisable par date de commit

Firestore attribue à chaque transaction une durée de commit qui représente un moment précis. Lorsque Firestore procède au commit d'une transaction dans la base de données, vous pouvez supposer que toutes les opérations de lecture et d'écriture ont lieu au moment de la transaction.

L'exécution réelle d'une transaction nécessite un certain temps. L'exécution d'une transaction débute avant la date de validation et l'exécution de plusieurs opérations peut se chevaucher. Firestore maintient l'isolation sérialisable et garantit que:

  • Firestore procède au commit des transactions dans l'ordre par date de commit.
  • Firestore isole les transactions des opérations simultanées avec un commit ultérieur.

En cas de conflit de données entre les opérations simultanées, Firestore utilise des contrôles de simultanéité optimistes et pessimistes pour résoudre les conflits.

Isolation dans une transaction

L'isolation de transaction s'applique également aux opérations d'écriture dans une transaction. Les requêtes et les lectures d'une transaction ne voient pas les résultats des écritures précédentes dans cette transaction. Même si vous modifiez ou supprimez un document dans une transaction, toutes les lectures de documents de cette transaction renvoient la version du document au moment de la validation, avant l'opération d'écriture de la transaction. Les opérations de lecture ne renvoient rien si le document n'existait pas alors.