Comment résoudre l'erreur « ERROR: 1023 DETAIL: Serializable isolation violation on table in Redshift » (Violation d'isolement sérialisable sur une table dans Redshift) ?

Date de la dernière mise à jour : 10/10/2022

Si j'exécute des opérations simultanées Amazon Redshift dans différentes sessions, le message suivant s'affiche : « ERROR: 1023 DETAIL: Serializable isolation violation on table in Redshift » (Violation d'isolement sérialisable sur une table dans Redshift). Comment puis-je résoudre cette erreur ?

Brève description

Les opérations d'écriture simultanées dans Amazon Redshift doivent être sérialisables. Cela signifie que les transactions doivent pouvoir être exécutées en série dans au moins une commande qui produit les mêmes résultats que si les transactions étaient exécutées simultanément. Pour plus d'informations, consultez la section Isolement sérialisable.

Reportez-vous à l'une des méthodes suivantes (ou à toutes) pour résoudre les erreurs d'isolement sérialisable :

  • Déplacer les opérations qui ne doivent pas nécessairement se trouver dans la même transaction pour l’atomicité afin qu’elles soient en dehors de la transaction
  • Forcer la sérialisation en bloquant toutes les tables dans chaque session
  • Utiliser l'isolement d’instantané pour les transactions simultanées

Solution

Déplacer les opérations qui ne doivent pas nécessairement se trouver dans la même transaction pour l’atomicité afin qu’elles soient en dehors de la transaction

Utilisez cette méthode lorsque des opérations individuelles au sein de deux transactions effectuent des renvois entre elles, ce qui pourrait affecter le résultat de l'une des transactions. Par exemple, supposons que deux sessions démarrent chacune une transaction :

Session1_Redshift = # BEGIN;
Session2_Redshift = # BEGIN;

Le résultat de l'instruction SELECT dans une transaction pourrait être affecté par l'instruction INSERT dans l'autre. Si elles sont exécutées en série, et ce, dans n'importe quel ordre, le résultat d'une instruction SELECT renvoie toujours une ligne de plus que si les transactions étaient exécutées simultanément. Étant donné qu'aucun ordre dans lequel les opérations peuvent être exécutées en série ne peut produire le même résultat que lorsqu'elles sont exécutées de manière simultanée, la dernière opération qui est exécutée entraîne une erreur d'isolement sérialisable :

Session1_redshift=# select * from tab1;
Session1_redshift =# insert into tab2 values (1);
Session2_redshift =# insert into tab1 values (1);
Session2_redshift =# select * from tab2;

Si le résultat des instructions SELECT n'est pas important (c'est-à-dire, que l'atomicité des opérations dans les transactions n'est pas importante), déplacez les instructions SELECT en dehors de leurs transactions. Par exemple :

Session1_Redshift=# BEGIN;
Session1_Redshift = # insert into tab1 values (1)
Session1_Redshift = # END;
Session1_Redshift # select * from tab2;
Session2_Redshift # select * from tab1;
Session2_Redshift =# BEGIN;
Session2_Redshift = # insert into tab2 values (1)
Session2_Redshift = # END;

Dans ces exemples, il n'y a pas de références croisées dans les transactions. Les deux instructions INSERT n'ont aucune influence l'une sur l'autre. Étant donné qu'il y a au moins un ordre dans lequel les transactions peuvent être exécutées en série et produire le même résultat que si elles étaient exécutées simultanément, les transactions sont sérialisables.

Forcer la sérialisation en bloquant toutes les tables dans chaque session

La commande LOCK bloque les opérations qui pourraient entraîner des erreurs d'isolement sérialisable. Lorsque vous utilisez la commande LOCK, veillez à effectuer les tâches suivantes :

  • Verrouillez toutes les tables affectées par la transaction, y compris celles affectées par des instructions SELECT en lecture seule au sein de la transaction.
  • Verrouillez les tables dans le même ordre, quel que soit l'ordre dans lequel les opérations sont effectuées.
  • Verrouillez toutes les tables au début de la transaction, avant d'exécuter toute opération.

Utiliser l'isolement d’instantané pour les transactions simultanées

L'option SERIALIZABLE (isolement sérialisable) applique une sériabilité stricte, dans laquelle une transaction pourrait échouer si le résultat ne pouvait ne pas être mappé dans un ordre de série des transactions exécutées simultanément.

L'option SNAPSHOT ISOLATION (isolement d'instantané) permet une plus grande simultanéité, dans laquelle les modifications simultanées à différentes lignes dans la même table sont apportées avec succès.

Les transactions continuent d'être menées sur la dernière version appliquée de la base de données, ou instantané.

L'isolement des instantanés est défini sur la base de données à l'aide du paramètre ISOLATION LEVEL (niveau d’isolement) de la commande CREATE DATABASE ou ALTER DATABASE.

Pour afficher le modèle de simultanéité utilisé par votre base de données, exécutez l'exemple de requête STV_DB_ISOLATION_LEVEL ci-après :

SELECT * FROM stv_db_isolation_level;
The database can then be altered to SNAPSHOT ISOLATION:
ALTER DATABASE sampledb ISOLATION LEVEL SNAPSHOT;

Tenez compte de ce qui suit lorsque vous modifiez le niveau d'isolement d'une base de données :

  • Vous devez disposer du privilège superutilisateur ou CREATE DATABASE pour la base de données actuelle afin de modifier le niveau d'isolement de la base de données.
  • Vous ne pouvez pas modifier le niveau d'isolement de l'environnement de base de données DEV.
  • Vous ne pouvez pas modifier le niveau d'isolement au sein d'un bloc de transactions.
  • La commande alter isolation level échoue si d'autres utilisateurs sont également connectés à la base de données.
  • La commande alter isolation level peut modifier les paramètres du niveau d'isolement de la session en cours.

Cet article vous a-t-il été utile ?


Besoin d'aide pour une question technique ou de facturation ?