- PR -

ConnectionのAutoCommitについて

投稿者投稿内容
永井和彦
ぬし
会議室デビュー日: 2002/07/03
投稿数: 276
お住まい・勤務地: 東京都
投稿日時: 2004-01-03 17:50
引用:

情報ソース??
「SELECTにCommit不要」の部分は、書いてるとおり
私の勝手な思いこみですし、「そうでは無い」と思ったのは
一連のスレッドの中で皆さんがCommitないしRollbackを
必ずしていると言う回答からですが?



申し訳有りません。引用部分が不適切でした。
もぐさんの投稿の以下の部分を引用するべきでした。

引用:

でないと、不用意にトランザクション時間が長くなってしまいそうです。



この部分ですね。これに対して「不用意にトランザクション時間が長くなってしまうとどういう不利益があるんでしょうか?」と訊きたかった……つまり、その直前のおかもとさんの投稿の最後で提示されている疑問

引用:

不用意にトランザクションが長くなることの実害に
どんなものが有るのでしょうか?
やはりSELECTしているだけでも、RollBackするための
情報(ログ?)を記録しているのが無駄とかですか?



と、全く同じ内容でした。
トランザクションが不用意に長くなってしまうことの不都合に関して外部情報ソース等ありましたら教えていただけないでしょうか>もぐさん

---

……で、他も色々と不明瞭な記述が目立ちますね(TT<2004-01-02 03:39の私(永井)
夜中に寝惚けた頭で投稿したりしたからでしょう(と思いたい)

引用:

で、関連で思ったのですが、serializableを採用している場合はconnection poolingの利用に際して留意が必要かも知れません。下手をするとpoolからconnectionを取得したタイミングではなく、前回poolに戻した瞬間のスナップショット



に関しては、poolにconnectionを返却するときに、一律commit/rollbackした場合の話です。何もせずに返却しているなら、もっと酷くて、どの時点のデータを読み込んでしまうのか分かったものではないですね。

引用:

ところで、ただ単純にselectを発行しているだけでしたら、とりあえずrollbackセグメントには何も書き込まれないような気がするのですが……実際には何か(ログ?)が記録されているんでしょうか?



に関しては、前提条件「よく使われていると思われるRDBMSのデフォルトのトランザクション隔離レベルであるread commitedでは」が抜けちゃっていました。本当に穴だらけの投稿で申し訳ないです。
永井和彦
ぬし
会議室デビュー日: 2002/07/03
投稿数: 276
お住まい・勤務地: 東京都
投稿日時: 2004-01-03 18:10
で、原題に返ったようなので、もう一度初心に戻って……

引用:

通常は AutoCommit=true で、これから実行したい、
一連の操作に対するトランザクションを
開始したいときにfalseにするのでは無いのでしょうか?



「トランザクションを意識する必要のある処理を記述する際には必ずconnection.setAutoCommit(false)を実行して下さい」というコーディングルールにするというのは、個人的にはちょっと怖い気がします。
それと言うのも、AutoCommitのON/OFFに関するバグ(同時実行時の整合性等)は埋もれてしまい易そうに思うからです。
まあ、まともなテストしていれば検出出来るのかも知れないですが……

運用を開始した後に
「たまに変なデータが発生するんだよね」
……というオチになりそうな気がします。

引用:

(通常は一連の操作をストアドプロシジャ書くでしょうけども)



私はプロシージャ記述をルールにしているプロジェクトには参加したことないです……
もぐ
会議室デビュー日: 2002/12/06
投稿数: 13
投稿日時: 2004-01-04 15:16
すみません、かなり言葉足らずでした。
Connectionのデフォルト値が AutoCommit=true となっているのは、
もし AutoCommit=false がデフォルト値だったら、commit/rollback/close するまで
トランザクションがかかりっぱなしになってしまうので、
下手なプログラマが書くコードだと、まずいことになるとの考慮から、
仕様としてConnectionのAutoCommitのデフォルト値が true に
なっているのではないのかなと思った次第です。

で、プログラマが必要と思った時に AutoCommit=false にして、
次のSQLからトランザクションを開始しなさいと。

ただし、トランザクションが長くなることへの懸念ですが、
データベースエンジンの種類と隔離レベルの設定等によっては
他の更新トランザクション(更新ロック)をブロックしたり
デッドロック等の要因にもなりえると思います。

といいつつも私自身は、通常select時でもデータの一貫性を
保障してもらうためにトランザクション内で処理を実行しています。

一般的な通常業務(ちょっと意味不明...)のRDBアクセスだと、
トランザクションを必要(データ一貫性が必要)とするケースが圧倒的に多い
と思うので、私の場合はテスト以外では必ず
「AutoCommit=falseで始め、最後にcommit or rollbackする」
という一貫したコーディングスタイルになっています。
---- begin こんな雰囲気 ----
try{
 con.setAutoCommit( false );
 処理(selectでもupdateでもinsertでもdeleteでも...)
 con.commit();
}catch(...){
 con.rollback();
}finally{
con.close();
}
---- end こんな雰囲気 ----
(個人的には AutoCommit=false がデフォルト値であって欲しい)

また、複数処理をストアドプロシジャとして記述するのも、
DBクライアントとDBサーバ間で何往復間ものやりとりの間
トランザクションがかかりっ放しだといやなので(特に更新系)、
DBサーバ上で稼動するストアドプロシジャとして記述すれば
DBクライアントからはストアドプロシジャ名とパラメータのみ
DBサーバへ送信し、サーバで複数処理して結果をDBクライアントへ
返却するので、効率的ではないでしょうか?
(エンジンによってはストアドプロシジャはプリコンパイル等
 されているでしょうから、さらに効率的)



[ メッセージ編集済み 編集者: もぐ 編集日時 2004-01-04 15:18 ]

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