setAutoCommit(False)の状態で
insertもしくは、updateのsqlを流して、
commitを呼ばずにcloseした場合、
commitされるのでしょうか?rollbackされるのでしょうか?
環境は、Oracleですが、JDBCの仕様としては
どうなるのでしょうか?
ちょっとOracleのソースを探したかったのですが、見つけられませんでした。
(OTNあたりにも載ってそうな情報ですが…。)
上記の動作はいわゆる「暗黙のコミット」だと思います。
※ 暗黙コミット
COMMIT 命令を伴わないコミット操作。アプリケーションの正常終了時や DDL 実行の前後に発生する。
トランザクション中に DDL など実行しないよ? と思われるかもしれないがあるが、TRUCATE TABLE は DDL である。
conn.close()で接続が正常に終了しているため、暗黙コミットが働いているものと思われます。
SQL*Plusを使っている場合、commitと入力せずにexitなどでSQL*Plusを終了しても自動的にcommitされてしまう現象と同じだと思います。
他のRDBMSについては詳しくないのでよくわからないのですが、おそらくJDBCの仕様とは関係がなく、Oracleの仕様ではないでしょうか。
試しに実験してみました。
DBはOracle10g XEです。
開発環境はJDeveloper10gです
try{ conn = db.getConnection(); conn.setAutoCommit(false); ps = conn.prepareStatement("insert into hoge values('foo','bar','boo')"); ps.executeUpdate(); } finally { try { conn.close(); } catch (Exception e) { e.printStackTrace(); } }
こんな感じのソースでやってみてJDevloperからDBをみてみると正常に挿入されているみたいです。
念のためSQLDeveloperでもみてみましたが、挿入されているみたいです。
コミットせずにクローズすると
コミットされてしまうのですね。。。
保証されている動作なのか気になるところです。
ちょっとOracleのソースを探したかったのですが、見つけられませんでした。
(OTNあたりにも載ってそうな情報ですが…。)
上記の動作はいわゆる「暗黙のコミット」だと思います。
※ 暗黙コミット
COMMIT 命令を伴わないコミット操作。アプリケーションの正常終了時や DDL 実行の前後に発生する。
トランザクション中に DDL など実行しないよ? と思われるかもしれないがあるが、TRUCATE TABLE は DDL である。
conn.close()で接続が正常に終了しているため、暗黙コミットが働いているものと思われます。
SQL*Plusを使っている場合、commitと入力せずにexitなどでSQL*Plusを終了しても自動的にcommitされてしまう現象と同じだと思います。
他のRDBMSについては詳しくないのでよくわからないのですが、おそらくJDBCの仕様とは関係がなく、Oracleの仕様ではないでしょうか。
なるほど。参考になります。
sql*plusだとそうなりますね。
おっしゃる通り、Oracleの仕様のような気がしますね。
ありがとうございます。
JDK5.0のAPIドキュメントには、Connectionの説明にこんなことが書いてあります。
> 注: 各文を実行後、デフォルトでは、Connection オブジェクトは自動
> コミットモードになり、自動的に変更をコミットします。自動コミット
> モードが無効にされている場合、変更をコミットするにはメソッド
> commit を明示的に呼び出す必要があります。そうしないとデータベー
> スの変更は保存されません。
厳密には保証されてないようです。
"保存されません。" = "コミットされません"
だと嬉しいのですが。。
そうは、いかないようですね。
commitを止めたい時は、rollbackを明示的に入れるないと
問題が置きそうですね。
なるほど。参考になります。
sql*plusだとそうなりますね。
おっしゃる通り、Oracleの仕様のような気がしますね。
ありがとうございます。