Apache Derby を使っていてふと予想外のエラーが出た。
トランザクションの close 時に
- トランザクションがまだアクティブなときに接続をクローズすることはできません。
と例外が発生する。
きっと commit 漏れがあるのだろうと処理を見直すが
どうもそうではないらしい。
いろいろ試してみたところこれが発生する理由は
- トランザクションで何も更新せずに commit した時
だった。
(こんなの、古いバージョンでは出なかった気もするが)
これは
トランザクションを開始しておきながら読み込みしか行わず書き込みをしないのなら
トランザクションなんか使うな
という意味だろうか。
あるいは
更新しないのならば setReadOnly(true) を入れるべきだ
という考え方かもしれない。
しかし。
読み込んだ内容によって
更新が発生するかしないかが変わるような処理は多々あると思う。
この仕様は非常に微妙だ。
解決法
微妙ではあるが、どうしようもない。
これはもしかしたら自分が知らないだけで
とても一般的なこと( Derby に限ったことではない)かもしれない。
コードで何とか回避するしかない。
その対策は、とても簡単にできた。
- commit したあと、すぐに rollback する
で良い。
ソースはこのようなイメージになる。
transactoin.begin();
try {
処理();
transaction.commit();
} catch {
transaction.rollback();
} finally {
transaction.close();
}
private void commit() {
transaction.commit();
transaction.rollback();}
更新が無くても rollbak して close するぶんには許されるらしい。
ちょっと不思議だ。