- - PR -
ConnectionのAutoCommitについて
| 投稿者 | 投稿内容 | ||||||||
|---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2003-12-27 01:05
みなさんありがとうございます。
出来るだけシンプルにしたいというのは 私自身も常に思っているので、特別な 場合を除いて参照、更新に関わらず 必ず明示的にコミットする方向で 今後の開発は行っていこうと思います。 | ||||||||
|
投稿日時: 2003-12-29 12:30
ふと自分のコメントを読み返してみたら誤解されそうな表現だったので、追記しておきます。
私の意見は「AutoCommitは常にfalse、もしトランザクション内でSELECT文しか実行していなくても、処理が正常に終わればコネクションクローズ前にコミットする」です。 | ||||||||
|
投稿日時: 2003-12-29 13:19
ただの好みの問題かも知れませんが、個人的に 「Commit(タイミング)は実装者に常に明確に意識されているべき」 と思っているので、今までの経験プロジェクトでは常にデフォルトをRollbackにしてきています。 「Commitがデフォルト」が世間一般の共通解釈だとすると、今まで共にやったメンバーに悪かったかなー……とも思うのですが。 実際のところ、その辺どうなんでしょうか? 以前ちょっと実験したんですが、元々のデフォルト状態では ・AutoCommit=ON ・ConnectionClose時=Commit ……と、自分が期待していた(/いる)状態と全く逆だったような記憶があります。 #JDBCでOracle8iに接続していたハズ<実験時 | ||||||||
|
投稿日時: 2003-12-29 14:31
こんにちは、カーニーです。
デフォルトというのはAutoCommit=falseのときに、commit()もrollback()もせずにclose()したときのことをおっしゃっていますか? それについては今までのコメントで全く考慮していませんでしたが、その場合には私も共通関数内やコネクションプーリング管理クラス内などでrollbackさせるのがよいと思います。
確かに私も逆のほうが安全でよいと思います。 | ||||||||
|
投稿日時: 2003-12-29 23:36
はじめまして。
通常は AutoCommit=true で、これから実行したい、 一連の操作に対するトランザクションを 開始したいときにfalseにするのでは無いのでしょうか? でないと、不用意にトランザクション時間が長くなってしまいそうです。 (通常は一連の操作をストアドプロシジャ書くでしょうけども) | ||||||||
|
投稿日時: 2004-01-01 01:41
もぐさんの考えがJDBC的には推奨なのでしょうね。
ただ、true(デフォルト)にしたりfalseにしたり。 Commitしたりしなかったり(自動的にCommitされている) するよりも、常に実装する側でコントロールする方が 安全だし、コードもシンプルで一貫性のあるものになる と皆さん主張されているのだと思います。 私自身は「SELECTにCommitなんて要らないだろう?」 と思っていましたが、どうやらそうでは無い模様。 不用意にトランザクションが長くなることの実害に どんなものが有るのでしょうか? やはりSELECTしているだけでも、RollBackするための 情報(ログ?)を記録しているのが無駄とかですか? | ||||||||
|
投稿日時: 2004-01-02 03:39
トランザクション隔離レベルが高い場合に、少々望ましくない状態になるのかも知れないです。 例えばOracleの場合、デフォルトのトランザクション隔離レベルはread commitedだったと思いますが、このレベルならさほど問題は無い気がします。 #なので、あまり意識レベルに上がって来ないのではないかと ただ、例えばrepeatable read隔離レベルでselectを実行したままcommitもrollbackもされなければ、その定義に従い、次回同じデータの読み込み要求があった時にも最初の読み込みの際と同じ結果を返してしまうと思います。そして、これは多分(そういうことを意識していない)実装者の意図に反しています。 また、同じデータの読み込み要求が再発生するか否かに関わらず、それに備えて何らかの準備をしておくことが必要だと思われますので、その辺りでシステムに無駄な負荷が発生する恐れがあるのではないでしょうか。 serializableだったりすると、ファントムリード防止の関係で更に色々とあるのかも知れません。色々の内容に関してはRDBMSの実装によるでしょうし、あんまり突っ込んで知りたいとも思いませんが。 で、関連で思ったのですが、serializableを採用している場合はconnection poolingの利用に際して留意が必要かも知れません。下手をするとpoolからconnectionを取得したタイミングではなく、前回poolに戻した瞬間のスナップショットを参照してしまうのではないかと思います。この隔離レベルの場合はgetConnectionしたら、まずbegin transaction(もしくはcommit/rollback)した方が安全そうですね。 ところで、ただ単純にselectを発行しているだけでしたら、とりあえずrollbackセグメントには何も書き込まれないような気がするのですが……実際には何か(ログ?)が記録されているんでしょうか?
お手数ですが、この部分の情報ソースを教えていただけないでしょうか? | ||||||||
|
投稿日時: 2004-01-03 00:19
新年早々お付き合い頂きありがとうございます。
情報ソース?? 「SELECTにCommit不要」の部分は、書いてるとおり 私の勝手な思いこみですし、「そうでは無い」と思ったのは 一連のスレッドの中で皆さんがCommitないしRollbackを 必ずしていると言う回答からですが? | ||||||||
