FirebirdSQL logo
RECORD_VERSION

Pour ce niveau d’isolement, l’une des deux valeurs caractéristiques supplémentaires peut être spécifiée, en fonction de la méthode de résolution des conflits souhaitée : RECORD_VERSION et NO RECORD_VERSION.Comme le montrent leurs noms, ils s’excluent mutuellement.

  • NO RECORD_VERSION est une sorte de mécanisme de verrouillage à deux phases. Dans ce cas, une transaction ne peut pas lire un enregistrement qui a été modifié par une transaction active concurrente (non confirmée).

    • Si la stratégie de résolution des verrouillages NO WAIT est spécifiée, une exception sera immédiatement levée.

    • Si la stratégie de résolution des verrouillages WAIT est spécifiée, elle fera en sorte qu’une transaction concurrente attende la fin ou le retour en arrière.Si une transaction concurrente est annulée ou si elle est terminée et que son identifiant est plus ancien (plus petit) que celui de la transaction en cours, les modifications de la transaction en cours sont autorisées.Si une transaction concurrente est terminée et que son identifiant est plus récent (plus grand) que l’identifiant de la transaction actuelle, une erreur de conflit de verrouillage sera générée.

  • Lorsque vous spécifiez RECORD_VERSION, la transaction lit toujours la dernière version validée des enregistrements de la table, qu’il existe ou non des versions modifiées et non validées de ces enregistrements. Dans ce cas, le mode de résolution du verrouillage (WAIT ou NO WAIT) n’a aucun effet sur le comportement de démarrage d’une transaction.

Dans l’API Firebird, le mode de résolution de conflit NO RECORD_VERSION est représenté par la constante isc_tpb_no_rec_version,et RECORD_VERSION — isc_tpb_rec_version.

Warning

A partir de Firebird 4.0, ces options sont obsolètes. Par défaut, elles sont ignorées et la transaction READ COMMITTED READ CONSISTENCY est lancée. Cela peut être modifié en mettant le ReadConsistency (voir firebird.conf) à 0. Dans ce cas, les options ne sont pas ignorées et fonctionnent exactement comme dans les versions précédentes. Dans les versions futures, ce paramètre dans firebird.conf peut être supprimé.

READ CONSISTENCY

Si cette option est spécifiée, la transaction en mode d’isolation READ COMMITED prend un instantané persistant de la base de données pour la durée de l’instruction. Chaque nouvelle instruction de niveau supérieur crée son propre instantané de la base de données pour voir les dernières données validées. Les instructions imbriquées (triggers, procédures et fonctions stockées imbriquées, instructions dynamiques, etc.) utilisent le même instantané de la base de données que celui créé par l’instruction de niveau supérieur.

Dans l’API Firebird, la constante isc_tpb_read_consistency correspond à l’opérateur READ CONSISTENCY pour un instantané cohérent au niveau SQL.

Gestion des conflits de mise à jour

Lorsqu’une instruction est exécutée dans une transaction en mode d’isolation READ COMMITTED READ CONSISTENCY, la vue de la base de données est inchangée (similaire à une transaction SNAPSHOT). Le comportement de lecture est similaire à celui de la transaction READ COMMITTED RECORD_VERSION — l’opérateur n’attend pas que la transaction active soit terminée et parcourt la chaîne arrière, qui recherche la version de l’enregistrement visible dans le snapshot courant.

Pour le mode d’isolation READ COMMITTED READ CONSISTENCY, la gestion des conflits de mise à jour de Firebird est considérablement modifiée. Lorsqu’un conflit de mise à jour est détecté, la procédure suivante est effectuée :

  1. le mode d’isolation de la transaction est temporairement commuté sur READ COMMITTED NO RECORD VERSION ;

  2. Firebird pose un verrou sur l’enregistrement en conflit ;

  3. Firebird continue à évaluer les enregistrements restants pour les supprimer/mettre à jour dans le curseur, et continue à poser des verrous sur eux ;

  4. lorsqu’il n’y a plus d’enregistrements à extraire, un mécanisme est déclenché pour annuler toutes les actions effectuées par l’opérateur de niveau supérieur, et tous les verrous posés pour chaque enregistrement mis à jour/supprimé/bloqué sont conservés, tous les enregistrements insérés sont supprimés ;

  5. alors Firebird restaure le mode d’isolation de la transaction en tant que READ COMMITTED READ CONSISTENCY, crée un nouvel instantané de niveau opérateur et relance l’exécution de l’instruction de niveau supérieur.

Cet algorithme garantit que, après le redémarrage, les enregistrements déjà mis à jour restent verrouillés, qu’ils sont visibles pour le nouvel instantané et qu’ils peuvent être mis à jour à nouveau sans autre conflit.De plus, grâce au mode de cohérence de lecture, l’ensemble des enregistrements modifiés reste cohérent.

Note
Remarques
  • L’algorithme de redémarrage ci-dessus s’applique aux opérateurs UPDATE, DELETE, SELECT WITH LOCK et MERGE, avec ou sans clause RETURNING, exécutés directement depuis l’application utilisateur ou en tant que partie d’un objet PSQL (procédure stockée, fonction, déclencheur, EXECUTE BLOCK etc ;)

  • Si un opérateur de haut niveau UPDATE/DELETE est situé à un curseur explicite (WHERE CURRENT OF), Firebird saute l’étape (c) ci-dessus, c’est-à-dire qu’il ne récupère pas et ne pose pas de verrous pour les enregistrements restants du curseur ;

  • Si une instruction SELECT de niveau supérieur (ou un ensemble de données de retour EXECUTE BLOCK) et un conflit de mise à jour se produisent après qu’un ou plusieurs enregistrements ont été renvoyés à l’application, l’erreur de conflit de mise à jour est signalée comme normale et un redémarrage n’est pas lancé ;

  • le redémarrage n’est pas initié pour les opérateurs en blocs autonomes (IN AUTONOMOUS TRANSACTION DO …​) ;

  • après 10 tentatives, Firebird abandonne l’algorithme de redémarrage, supprime tous les verrous d’écriture, restaure le mode d’isolation de la transaction en tant que READ COMMITTED READ CONSISTENCY et signale un conflit de mise à jour ;

  • toute erreur non traitée à l’étape (c) ci-dessus arrête l’algorithme de redémarrage et Firebird continue le traitement de manière normale, c’est-à-dire que l’erreur peut être interceptée et traitée par le bloc PSQL WHEN ou signalée à l’application si elle n’est pas traitée ;

  • Les déclencheurs UPDATE/DELETE seront déclenchés plusieurs fois pour le même enregistrement si l’exécution de la déclaration a été relancée et l’enregistrement mis à jour/supprimé à nouveau ;

  • pour des raisons historiques, isc_update_conflict est signalé comme un code d’erreur secondaire avec le code d’erreur primaire isc_deadlock.