PostgreSQLでは、トランザクションでエラーが発生した場合(たとえば、挿入文が一意制約に違反した場合など)、トランザクション全体が中止され、コミットできず、行も挿入されません。PostgeSQLとOracleのデフォルトトランザクション管理
database=# begin;
BEGIN
database=# insert into table (id, something) values ('1','whatever');
INSERT 0 1
database=# insert into table (id, something) values ('1','whatever');
ERROR: duplicate key value violates unique constraint "table_id_key"
Key (id)=(1) already exists.
database=# insert into table (id, something) values ('2','whatever');
ERROR: current transaction is aborted, commands ignored until end of transaction block
database=# rollback;
database=# select * from table;
id | something |
-----+------------+
(0 rows)
あなたはそのあとに、エラーを無視して、複数の挿入を行うコミットのみに成功し、取引終了後にテーブルの行を挿入していることができ、「オン」または「インタラクティブ」にON_ERROR_ROLLBACKを設定することであることを変更することができます。オラクルで
database=# \set ON_ERROR_ROLLBACK interactive
、これは私に驚き、デフォルトトランザクション管理行動、です。これは完全に直観的で危険なものではありませんか?
私はトランザクションを開始するときに、すべてのステートメントが成功したことを確認したいと思います。私の複数の挿入物が何らかの種類のオブジェクトまたはデータ構造を含む場合はどうでしょうか?私はデータベース内のデータ状態を完全に認識しなくなり、コミット後にそれをチェックする必要があります。 挿入のいずれかが失敗した場合は、最初のエラーの後に他の挿入がロールバックされるか評価されないようにしたいと思います。これはPostgreSQLでの処理方法とまったく同じです。
Oracleにはこのようなトランザクション管理方法がデフォルトとして組み込まれているのはなぜですか?なぜ、それは良い方法であると考えられますか?例えば
、いくつかのランダムな男here in comments
これは非常に巧妙な機能です。
私も、このことを理解していない:
「通常、あなたが作る任意のエラーが 例外をスローし、現在のトランザクションがアボート としてマークされるようになりますこれは...行動SANEと期待されています」いいえ、それは本当にありません。 Oracleはこのように動作しませんし、MySQLも動作しません。私は MSSQLまたはDB2の経験がありませんが、私はそれぞれ のいずれかの方法で動作しない1ドルを賭けるでしょう。構文 のエラーやそれ以外のエラーが原因でトランザクションが中止されるという直感的な理由はありません。 この動作が必要なPostgres にはいくつかの制限があります。あるいは、他の誰もが無視できないようなSQL標準の一部であるわかりにくい に準拠していると思います。 API/UXの理由で、このように動作する理由はありません。
我々は、この病理学的挙動について を開発したすべての回避策を誇りに思うべきではありません。それはITストックホルム症候群のようなものです。
取引の定義さえ違反していませんか?
トランザクションは、データベース内で実行さ 各作業単位はその 全体が完全または全く効果がありませんしなければならないのいずれかと述べて、「オール・オア・ナッシング」の命題を提供しています。
良い点!たぶん、それをやり遂げるための議論があるかもしれません。ただ、私はOracleの方法では「利便性」を除いて何も表示されません。 – Snifff
_人がOracleを使用するとNULL = NULLが真ではないと予想しています。 –
@コンスタンチンソロキンいいえ、私は間違っていました。私が考えていたのは、Oracle 9iでは '' 'IS NULL'です。 http://stackoverflow.com/q/13278773/398670。私はDBMSが 'NULL = NULL'が真だった場所を覚えていません...古いMS SQL? Microsoft Access/JETエンジン?古いMYSQL? –