ini pertanyaan yang menarik!
Ketika Oracle menemukan kesalahan, itu akan mengembalikan pernyataan saat ini , bukan transaksi. Pernyataan adalah instruksi tingkat atas apa pun, dapat berupa pernyataan SQL (INSERT, UPDATE...) atau blok PL/SQL.
Ini berarti bahwa ketika sebuah pernyataan (misalnya prosedur pl/sql dipanggil dari java) mengembalikan kesalahan, Oracle akan menempatkan transaksi dalam keadaan logis yang sama seperti sebelum panggilan. Ini sangat membantu, Anda tidak perlu khawatir dengan prosedur yang setengah dijalankan (**).
Utas ini di AskTom mencakup topik yang sama:
[pernyataan] SEPENUHNYA terjadi atau SEPENUHNYA TIDAK terjadi dan cara kerjanya adalah database melakukan persamaan logis dengan:
begin
savepoint foo;
<<your statement>>
exception
when others then rollback to foo;
RAISE;
end;
Fitur ini, menurut saya, adalah mengapa jauh lebih mudah untuk menulis kode database (*) di pl/sql daripada dalam bahasa lain.
(*) kode yang berinteraksi dengan Oracle DB tentunya, saya kira bahasa prosedural asli dari DBMS lain memiliki fitur yang serupa.
(**) Ini hanya menyangkut DML karena DDL tidak bersifat transaksional di Oracle. Hati-hati juga dengan beberapa paket DBMS yang memperbarui kamus data (seperti DBMS_STATS
), mereka sering melakukan perubahan seperti DDL dan mengeluarkan komit. Lihat dokumentasi jika ragu.
Pembaruan: perilaku ini adalah salah satu konsep yang paling penting dalam PL/SQL, saya akan memberikan contoh kecil untuk menunjukkan atomicity dari pernyataan pl/sql :
SQL> CREATE TABLE T (a NUMBER);
Table created
SQL> CREATE OR REPLACE PROCEDURE p1 AS
2 BEGIN
3 -- this statement is successful
4 INSERT INTO t VALUES (2);
5 -- this statement will raise an error
6 raise_application_error(-20001, 'foo');
7 END p1;
8 /
Procedure created
SQL> INSERT INTO t VALUES (1);
1 row inserted
SQL> EXEC p1;
begin p1; end;
ORA-20001: foo
ORA-06512: at "VNZ.P1", line 5
ORA-06512: at line 2
SQL> SELECT * FROM t;
A
----------
1
Oracle telah mengembalikan transaksi ke titik sebelum memanggil p1. Tidak ada pekerjaan setengah-setengah yang dilakukan. Seolah-olah prosedur p1 tidak pernah dipanggil.