2009-09-23 17 views
8

これは、ばかな質問のように感じるが、私は、トランザクション管理上のOracleコンセプトガイドでは、以下を参照してください。Oracleはトランザクションをエラーでロールバックしますか?

のいずれかが、次の時にトランザクションが終了

が発生します。

ユーザーが発行

COMMITまたはROLLBACK SAVEPOINT節のないステートメント。

ユーザーは、 のようなDDL文を実行します。CREATE、DROP、RENAME、またはALTER。 現在のトランザクションにDML 文が含まれている場合、Oracleは最初に トランザクションをコミットしてから、 文トランザクションとしてDDL文を実行してコミットします( )。

ユーザーがOracleから切断します。 現在のトランザクションがコミットされています。

ユーザープロセスが異常終了します。 現在の取引は転記されました 。

最後の点は、エラーが発生したクエリを発行するとトランザクションがロールバックされることを意味していますか?

+0

実際、私にとっては非常に興味深い質問のようです。 Postgresはエラー時にロールバックし、私はしばしばそれが迷惑であることを発見しました(そして、オラクルが同様のことをしたかどうか疑問に思っています)。 – jsight

+0

エラー時にロールバックしたくない場合は、なぜトランザクションを使用していますか?これはトランザクションの主な目的の1つです。 –

+0

@Oliver:私は必ずしも欲しいと思っていません。彼らの働き方を知りたいだけです。 –

答えて

7

このコンテキストの「ユーザー・プロセス」は、Oracleへの接続を作成するクライアント・マシン上で実行されているプロセスを指しています。つまり、アプリケーションA(SQL*Plus、TOADなど)を使用してOracleに接続する場合、ユーザー・プロセスはSQL*Plus、TOADなどです。トランザクションの途中でそのユーザー・プロセスが終了すると、そのトランザクションロールバックされます。これは、PMONがクライアントの死亡を発見するとすぐに発生します。これは時間がかかることがあります。ユーザー・プロセスの障害と、コマンドを発行していないユーザー・プロセスとを区別することは必ずしも容易ではありません。瞬間。

1

私はJustinに同意します、彼の洞察は正しいです。追加情報の追加:アプリケーション開発者は、エラーが発生した場合には明示的にロールバック・コマンドを呼び出す必要があります。つまり、ステートメントを適切なトランザクションブロックにグループ化することも検討する必要があります。トランザクショナルブロックとロールバックは、さまざまなテクノロジによって異なる方法で処理されますが、理解を深めるための調査が必要です。

12

これは興味深い質問です!

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が呼び出されたことがないかのようです。

+1

文とPL/SQLブロックについて間違っています。 PL/SQLブロックは、INSERT、UPDATEまたはDELETE以外の文ではありません。 PL/SQLブロックがエラーをスローし、コードのようなセーブポイント処理がない場合、半分実行されるプロシージャについて心配する必要があります。 – Christian13467

+2

クリスチャン、間違っています。クライアントから呼び出された最上位レベルのPL/SQLブロックによって例外が発生した場合、そのブロックの起動前のポイントにロールバックされます(介在するPL/SQLでコミットが発生していないことが前提です)。 –

+0

@Christian:私は私の答えを更新しました。うまくいけば、これは私が説明しようとしていた概念を明確にします。 –

関連する問題