Oracle
 sql >> Base de données >  >> RDS >> Oracle

Comment rendre MERGE sérialisable

L'exception que vous voyez est une conséquence directe de l'utilisation de la sérialisation stricte. Si vous avez plusieurs transactions actives simultanément, chacune démarrée avec SET TRANSACTION ISOLATION LEVEL SERIALIZABLE, lorsque l'une d'elles s'engage, les autres obtiendront un ORA-08177. C'est ainsi que la sérialisation stricte est appliquée - la base de données lance un ORA-08177 dans toute session démarrée avec ISOLATION LEVEL SERIALIZABLE si une autre transaction s'engage dans une table dont la session sérialisable a besoin. Donc, fondamentalement, si vous avez vraiment besoin d'une sérialisation stricte, vous devez gérer intelligemment les ORA-08177, comme dans ce qui suit :

DECLARE
  bSerializable_trans_complete  BOOLEAN := FALSE;
  excpSerializable              EXCEPTION;
  PRAGMA EXCEPTION_INIT(excpSerializable, -08177);
BEGIN
  <<SERIALIZABLE_LOOP>>
  WHILE NOT bSerializable_trans_complete
  LOOP
    BEGIN
      SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;

      MERGE ...; -- or whatever

      COMMIT;

      bSerializable_trans_complete := TRUE;  -- allow SERIALIZABLE_LOOP to exit
    EXCEPTION
      WHEN excpSerializable THEN
        ROLLBACK;
        CONTINUE SERIALIZABLE_LOOP;
    END;
  END LOOP;  -- SERIALIZABLE_LOOP
END;

La sérialisation n'est pas magique, et elle n'est pas "gratuite" (où "gratuit" signifie "En tant que développeur, je n'ai rien à faire pour que cela fonctionne correctement"). Cela nécessite plus de planification et de travail de la part du développeur pour le faire fonctionner correctement, pas moins. Partagez et profitez.