これは興味深い質問です!
Oracleにエラーが発生すると、トランザクションではなく、現在の文がロールバックされます。 SQL文(INSERT、UPDATE ...)またはPL/SQLブロックにすることができます。
これは、文(javaからコールされたpl/sqlプロシージャなど)がエラーを戻す場合、Oracleはトランザクションをコール前と同じ論理状態にすることを意味します。これは非常に有益です。半分実行された手順(**)について心配する必要はありません。
This thread on AskTom covers the same topic:
[声明]のいずれか完全に起こるか、それは完全に起こらないと動作します 方法は、データベースが論理的同等んです:
begin
savepoint foo;
<<your statement>>
exception
when others then rollback to foo;
RAISE;
end;
これを私の意見では、他の言語よりもpl/sqlでデータベースコード(*)を書く方がずっと簡単です。
(*)コードはもちろん、Oracle DBとやりとりするものですが、他のDBMSのネイティブの手続き言語にも同様の機能があると思います。
(**)これは、OracleのDDL are not transactional以降、DMLのみに関するものです。また、データ・ディクショナリ(例えば、DBMS_STATS
)を更新するDBMSパッケージには注意が必要です。DDLのような変更やコミットを行うことがよくあります。不確かな場合はdocumentationを参照してください。
更新:
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
オラクルがありますこの動作は、PL/SQLの中で最も重要な概念の一つであり、私はPL/SQL文のアトミックを証明するために、小さな例を提供しますp1を呼び出す直前にトランザクションをロールバックします。半分の作業はありません。これは、プロシージャーp1が呼び出されたことがないかのようです。
実際、私にとっては非常に興味深い質問のようです。 Postgresはエラー時にロールバックし、私はしばしばそれが迷惑であることを発見しました(そして、オラクルが同様のことをしたかどうか疑問に思っています)。 – jsight
エラー時にロールバックしたくない場合は、なぜトランザクションを使用していますか?これはトランザクションの主な目的の1つです。 –
@Oliver:私は必ずしも欲しいと思っていません。彼らの働き方を知りたいだけです。 –