Incohérence dans la lecture répétable

10

http://www.postgresql.org/docs/9.2/static/transaction-iso.html

Le mode de lecture répétable offre une garantie rigoureuse que chaque transaction voit une vue complètement stable de la base de données. Cependant, cette vue ne sera pas nécessairement toujours cohérente avec une exécution en série (une à la fois) de transactions simultanées du même niveau. Par exemple, même une transaction en lecture seule à ce niveau peut voir un enregistrement de contrôle mis à jour pour montrer qu'un lot a été terminé mais ne pas voir l'un des enregistrements de détail qui fait logiquement partie du lot car il a lu une révision antérieure de l'enregistrement de contrôle . Les tentatives d'application des règles métier par des transactions s'exécutant à ce niveau d'isolement ne sont pas susceptibles de fonctionner correctement sans une utilisation prudente des verrous explicites pour bloquer les transactions en conflit.

N'est-ce pas une lecture fantôme, ce qui n'est pas possible en mode de lecture répétable?

La documentation indique qu'une requête dans une transaction de lecture répétée voit un instantané au début de la transaction, alors comment une requête peut-elle lire des données incohérentes?

Alice
la source

Réponses:

5

Voici ma lecture de cette section. J'admets que c'est déroutant.

Supposons que j'ai deux tables:

CREATE TABLE batch (
   id serial not null unique,
   control_code text primary key,
   date_posted date not null default now()
);

CREATE TABLE details (
   batch_id int not null references batch(id),
   description text,
   primary key(batch_id, description)
);

Supposons maintenant que nous insérions des enregistrements de lots et de détails dans différentes transactions. La session 1 insère un lot et commence à insérer des détails mais avant la fin, la session 2 démarre. La session 2 voit les informations d'en-tête du lot, mais n'attend pas les détails de la validation pour informer l'utilisateur qu'aucun enregistrement n'est trouvé. Maintenant, si votre lot et vos détails sont entièrement dans la même transaction, ce n'est jamais un problème.

cela différerait de sérialisable où vous vous attendriez à ce que l'insertion précédente soit terminée et validée ou annulée avant de déterminer s'il faut informer l'utilisateur qu'aucune ligne n'a été trouvée.

Chris Travers
la source
3

Il y a un document dans le wiki PostgreSQL qui montre certains problèmes qui peuvent survenir avec certaines combinaisons de transactions au niveau d'isolement des transactions REPEATABLE READ, et comment ils sont évités au niveau d'isolement des transactions SERIALIZABLE à partir de PostgreSQL version 9.1.

Il comprend également un exemple de la façon dont une transaction REPEATABLE READ-level READ-ONLY pourrait être capable de lire des données incohérentes.

907e
la source
@dezso Cela pourrait vous intéresser
907th
1

Les lectures fantômes (assurez-vous de ne pas les confondre avec les lectures non répétables) sont possibles dans le niveau d'isolement "Lecture répétable" ... en principe. Mais le comportement de facto de Postgresql lorsque vous sélectionnez «Lecture répétable» est plus fort que la norme (presque un isolement «sérialisable»), de sorte que, en fait, vous n'aurez pas de lectures fantômes. Documents :

Lorsque vous sélectionnez le niveau Read Uncommitted, vous obtenez vraiment Read Committed et les lectures fantômes ne sont pas possibles dans l'implémentation PostgreSQL de Repeatable Read , donc le niveau d'isolement réel peut être plus strict que ce que vous sélectionnez.

Maintenant, qu'en est-il de cette mise en garde "cette vue ne sera pas nécessairement toujours compatible avec une exécution en série (une à la fois) de transactions simultanées du même niveau"? Je pense (je ne suis pas sûr) que cela signifie que cela signifie que l'instantané "de l'extérieur" (fixé au début de la transaction) peut éventuellement inclure des lignes d'autres transactions mais ne parvient pas à inclure d'autres lignes de cette même transaction.

leonbloy
la source