sql >> Base de Datos >  >> RDS >> Oracle

BEGIN - END bloquea transacciones atómicas en PL/SQL

En primer lugar, BEGIN..END son meramente elementos sintácticos y no tienen nada que ver con transacciones.

En segundo lugar, en Oracle, todas las declaraciones DML individuales son atómicas (es decir, tienen éxito en su totalidad o revierten cualquier cambio intermedio en el primer error) (a menos que use la opción EXCEPTIONS INTO, que no abordaré aquí).

Si desea que un grupo de instrucciones se trate como una sola transacción atómica, haría algo como esto:

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;

De esa manera, cualquier excepción hará que las declaraciones en este bloque se reviertan, pero cualquier declaración que se haya ejecutado antes de este bloque no se revertirá.

Tenga en cuenta que no incluyo un COMMIT; por lo general, prefiero que el proceso de llamada emita el compromiso.

Es cierto que un bloque BEGIN..END sin controlador de excepciones manejará esto automáticamente por usted:

BEGIN
  INSERT INTO .... ; -- first DML
  UPDATE .... ; -- second DML
  BEGIN ... END; -- some other work
  UPDATE .... ; -- final DML
END;

Si se genera una excepción, se revertirán todas las inserciones y actualizaciones; pero tan pronto como desee agregar un controlador de excepciones, no se revertirá. Así que prefiero el método explícito usando puntos de guardado.