Oracle
 sql >> Database >  >> RDS >> Oracle

Come rendere serializzabile MERGE

L'eccezione che stai vedendo è una conseguenza diretta dell'utilizzo di una serializzazione rigorosa. Se hai più di una transazione attiva contemporaneamente, ciascuna è iniziata con SET TRANSACTION ISOLATION LEVEL SERIALIZABLE, quando una di esse esegue il commit, le altre riceveranno un ORA-08177. Ecco come viene applicata una serializzazione rigorosa:il database genera un ORA-08177 in qualsiasi sessione avviata con ISOLATION LEVEL SERIALIZABLE se un'altra transazione esegue il commit in una tabella di cui la sessione serializzabile ha bisogno. Quindi, in pratica, se hai davvero bisogno di una serializzazione rigorosa, devi gestire gli ORA-08177 in modo intelligente, come di seguito:

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 serializzazione non è magica e non è "gratuita" (dove "gratuito" significa "io come sviluppatore non devo fare nulla per farlo funzionare correttamente"). Richiede più pianificazione e lavoro da parte dello sviluppatore per farlo funzionare correttamente, non meno. Condividi e divertiti.