- PR -

ConnectionのAutoCommitについて

投稿者投稿内容
おかもと
大ベテラン
会議室デビュー日: 2003/06/08
投稿数: 182
投稿日時: 2003-12-26 11:09
JDBCではConnectionは通常AutoCommitになっており、
トランザクションを意識する必要が有る場合はsetAutoCommit(false)
する必要が有ると思います。

過去の開発ではCommit/Rollbackはアプリケーションで制御するので、
更新系処理では必ずAutoCommitはfalse。また、照会系の処理では
そもそもCommitする必要は無いためか、これも同じくfalseと
しておりました。(正確に言えば、JNDI/DataSourceからConnectionを
取得するクラスを作成する人が、デフォルトsetAutoCommit(false)して
おりました。)

私自身も旧バージョンのStrutsのstruts-config.xmlでデータソース取得の
AutoCommitのデフォルト指定をする項目が有ったので、とりあえず
falseにしておいてよいのかなと思っていましたが、今回WebSphereを使用する
ことになって、ログを眺めておりましたら。

「リソース jdbc/db が、未解決の LocalTransactionContainment のクリーンアップでロールバックされました。」

と言ったエラーが出力されておりました。確かに、SELECTを発行するだけの処理では
Commit/Rollbackをしておりません。

そこで質問なのですが、通常はやはりAutoCommitはtrueのままにしておいて、
必要に応じてfalseにするのでしょうか?SELECTするたびにCommitするのは
無駄と言うのもネットで見かけたのですが・・・。

まあ、最終的には製品に依存するということでしょうが、参考までに意見を
聞かせていただければと思います。
ローレル
会議室デビュー日: 2003/11/16
投稿数: 3
投稿日時: 2003-12-26 14:37
検索用と更新用のデータソースを用意すれば良いのではないでしょうか?
検索用 AutoCommit true jdbc/conn
更新用 AutoCommit false jdbc/txconn
永井和彦
ぬし
会議室デビュー日: 2002/07/03
投稿数: 276
お住まい・勤務地: 東京都
投稿日時: 2003-12-26 16:19
引用:

そこで質問なのですが、通常はやはりAutoCommitはtrueのままにしておいて、
必要に応じてfalseにするのでしょうか?SELECTするたびにCommitするのは
無駄と言うのもネットで見かけたのですが・・・。



私の場合はConnection取得する部分でsetAutoCommit(false)して、ConnectionをCloseする部分でclose直前にrollbackさせています。
もちろん、こんなコードが散らばるのは嫌なので、共通で吸収しますが。
おかもと
大ベテラン
会議室デビュー日: 2003/06/08
投稿数: 182
投稿日時: 2003-12-26 16:26
なるほど、そういう方法もあるのですね。
いずれにしても検索と更新は使い分けると言う
考え方ですね。

トランザクションの開始と終了を明示的に示す仕組みを
作る(あるいは使う)方が見た目にわかり易いような
気がしてきました。(次回の開発の課題だな)
永井和彦
ぬし
会議室デビュー日: 2002/07/03
投稿数: 276
お住まい・勤務地: 東京都
投稿日時: 2003-12-26 16:35
引用:

いずれにしても検索と更新は使い分けると言う
考え方ですね。



いえ、あの……全く区別していないです。
参照系も更新系も全てが

コネクション取得→(ごにょごにょ)→RollBack→コネクション開放

としているということです。
#(ごにょごにょ)がそれぞれの処理
おかもと
大ベテラン
会議室デビュー日: 2003/06/08
投稿数: 182
投稿日時: 2003-12-26 17:55
すみません。ローレルさんの投稿を読んで返答を
書いている間に永井さんが投稿されたようで、
永井さんの投稿は今読みました。

私の考えはどちらかと言えば永井さんよりですね。
カーニー
ぬし
会議室デビュー日: 2003/09/04
投稿数: 358
お住まい・勤務地: 東京
投稿日時: 2003-12-26 19:08
引用:

おかもとさんの書き込み (2003-12-26 11:09) より:
そこで質問なのですが、通常はやはりAutoCommitはtrueのままにしておいて、
必要に応じてfalseにするのでしょうか?SELECTするたびにCommitするのは
無駄と言うのもネットで見かけたのですが・・・。



Commitしても問題ないと思いますけどね。
当然ながらDB製品に依存する話ですけど、一般的にはコミットのタイミングでトランザクションログがディスクに同期書き込みされますよね。

でもSELECTだけだと、そもそも書き込むべきトランザクションログがほとんど発生していないはずなので、コミットしても余計な負荷は微々たるものなんじゃないかと思います。

私は更新だろうと参照だろうと、ノーエラーなら素直にコミットします。
Emacs信者
常連さん
会議室デビュー日: 2003/08/10
投稿数: 38
投稿日時: 2003-12-26 20:09
僕もカーニーさんと同意見です。
全てのパターンで同一の処理が適用できる方が、コードがシンプルになると思いますし。

select文の実行にかかる時間が長ければ、commitのオーバヘッドは無視できるのではないでしょうか。

もし、細かいselect文を大量に実行するようなタスクが存在するのなら、
それはもう共通的な処理をすることをあきらめて、割り切ってしまえばいいと僕は思います。

たとえば、ローレルさんがおっしゃる通りデータソースを使い分けるとか、
もしくは、"JDBC For Reading"のような感じで。

スキルアップ/キャリアアップ(JOB@IT)