はじめに
RDBMSはMySQLしかほとんど触ったことがなく、先日初めて業務でOracle Databaseに触れました。
前任者が残した、マスタデータをINSERTする以下のようなSQLを目にし、「なんでBEGIN
がなくてCOMMIT
だけあるの?」と困惑したので、調べて簡単にまとめました。
-- ユーザー種別
TRUNCATE TABLE user_types;
ALTER TABLE user_types MODIFY (id GENERATED ALWAYS AS IDENTITY (START WITH 1)) ;
INSERT INTO user_types(cd, name) VALUES (1, '一般ユーザー');
INSERT INTO user_types(cd, name) VALUES (2, '管理者ユーザー');
COMMIT;
ちなみに、前任者がBEGIN
を書き忘れたわけではないです(笑)
調べたこと
結論
-
結論を言うと、Oracle Databaseは常にトランザクションが有効なので、
BEGIN
を書いて明示的にトランザクションを開始する必要がありません -
終了するときは明示的に
COMMIT
またはROLLBACK
を書く必要があります1- トランザクション終了後、新しいSQLが実行されると、また自動的に新しいトランザクションが開始されます
注意点
明示的にCOMMIT
またはROLLBACK
を実行したとき以外にもトランザクションが終了する場合があります。
- トランザクションの対象にならないSQL文(つまりDDL文等)が実行されるとき
- Oracle Databaseユーティリティおよびツールを正常に終了したとき
このようなとき、トランザクションは暗黙的にコミットされてしまいます。意図しないコミットにつながるので注意しましょう。
補足と疑問点
後者について検証するため、Oracle SQL DeveloperでINSERT文を実行した後でウィンドウを閉じようとしたところ、コミットかロールバックをするようアラートを出してくれました。
てっきり上記の「Oracle Databaseユーティリティおよびツールを正常に終了したとき」に当てはまって、暗黙的にコミットされると思ったのですが。。
マニュアル(「参考」参照)を確認したところ、以下の記載がありました。
ノート:アプリケーションでは、プログラムを終了する前に、必ず明示的にトランザクションをコミットまたは取り消す必要があります。
これを見ると、Oracle SQL Developerは「Oracle Databaseユーティリティおよびツール」ではなく「アプリケーション」に当てはまるので、アラートが出たのかもしれません。
もし何かお分かりの方はコメントでご指摘いただけますと幸いです。
終わりに
1つのRDBMSに慣れきっていると、それが自分の中でSQLの常識になってしまい、他のRDBMSに触れたときに相違点があると驚きますね。
参考
-
自動コミットを設定していない場合 ↩