sql >> Databáze >  >> RDS >> Oracle

BEGIN - END blokové atomické transakce v PL/SQL

Nejprve BEGIN..END jsou pouze syntaktické prvky a nemají nic společného s transakcemi.

Za druhé, v Oracle jsou všechny jednotlivé příkazy DML atomické (tj. buď uspějí v plném rozsahu, nebo při prvním selhání odvolají jakékoli mezilehlé změny) (pokud nepoužijete možnost EXCEPTIONS INTO, kterou zde nebudu rozebírat).

Pokud chcete, aby se se skupinou příkazů zacházelo jako s jedinou atomickou transakcí, udělali byste něco takového:

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;

Tímto způsobem jakákoli výjimka způsobí, že příkazy v tomto bloku budou vráceny zpět, ale všechny příkazy, které byly spuštěny před tímto blokem nebude vrácena zpět.

Všimněte si, že nezahrnuji COMMIT - obvykle dávám přednost volajícímu procesu, aby vydal potvrzení.

Je pravda, že blok BEGIN..END bez obsluhy bez výjimky to automaticky zpracuje za vás:

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

Pokud je vyvolána výjimka, všechny vložky a aktualizace budou vráceny zpět; ale jakmile budete chtít přidat obslužnou rutinu výjimky, nevrátí se zpět. Dávám tedy přednost explicitní metodě pomocí bodů uložení.



  1. Funkce ROWIDTOCHAR() v Oracle

  2. Získejte ID objektu z jeho názvu na serveru SQL:OBJECT_ID()

  3. Rails, MySQL a Snow Leopard

  4. Mohu použít stream k VLOŽENÍ nebo AKTUALIZACI řádku na serveru SQL Server (C#)?