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

BEGIN - END bloco de transações atômicas em PL/SQL


Em primeiro lugar, BEGIN..END são meramente elementos sintáticos e não têm nada a ver com transações.

Em segundo lugar, no Oracle, todas as instruções DML individuais são atômicas (ou seja, elas são bem-sucedidas por completo ou revertem quaisquer alterações intermediárias na primeira falha) (a menos que você use a opção EXCEPTIONS INTO, na qual não entrarei aqui).

Se você deseja que um grupo de instruções seja tratado como uma única transação atômica, faça algo assim:
BEGIN
  SAVEPOINT start_tran;
  INSERT INTO .... ; -- first DML
  UPDATE .... ; -- second DML
  BEGIN ... END; -- some other work
  UPDATE .... ; -- final DML
EXCEPTION
  WHEN OTHERS THEN
    ROLLBACK TO start_tran;
    RAISE;
END;

Dessa forma, qualquer exceção fará com que as instruções neste bloco sejam revertidas, mas quaisquer instruções que foram executadas antes deste bloco não será revertido.

Observe que não incluo um COMMIT - geralmente prefiro que o processo de chamada emita o commit.

É verdade que um bloco BEGIN..END sem manipulador de exceção tratará isso automaticamente para você:
BEGIN
  INSERT INTO .... ; -- first DML
  UPDATE .... ; -- second DML
  BEGIN ... END; -- some other work
  UPDATE .... ; -- final DML
END;

Se uma exceção for levantada, todas as inserções e atualizações serão revertidas; mas assim que você quiser adicionar um manipulador de exceção, ele não será revertido. Então eu prefiro o método explícito usando savepoints.