Oracle
 sql >> Base de Dados >  >> RDS >> Oracle

Como tornar MERGE serializável


A exceção que você está vendo é uma consequência direta do uso de serialização estrita. Se você tiver mais de uma transação ativa simultaneamente, cada uma iniciada com SET TRANSACTION ISOLATION LEVEL SERIALIZABLE, quando qualquer uma delas confirmar as demais receberão um ORA-08177. É assim que a serialização estrita é imposta - o banco de dados lança um ORA-08177 em qualquer sessão iniciada com ISOLATION LEVEL SERIALIZABLE se outra transação for confirmada em uma tabela que a sessão serializável precisa. Então, basicamente, se você realmente precisa de serialização estrita, você precisa lidar com os ORA-08177 de forma inteligente, como a seguir:
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;

A serialização não é mágica e não é "gratuita" (onde "livre" significa "eu, como desenvolvedor, não preciso fazer nada para que funcione corretamente"). Requer mais planejamento e trabalho por parte do desenvolvedor para que funcione corretamente, não menos. Compartilhe e curta.