- PR -

コミット間隔

投稿者投稿内容
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2007-05-22 06:23
複数回コミットするという用件は、今まで経験したことがないのですが、複数回 BeginTransaction しなきゃいけないのかなぁ?

Dispose も忘れずに。
_________________
YASUYOKA
ベテラン
会議室デビュー日: 2007/03/19
投稿数: 71
投稿日時: 2007-05-22 10:30
引用:

未記入さんの書き込み (2007-05-20 12:10) より:
しかし性能を向上させるためには、コミット間隔を50〜100件にするのが
自明の理だと思っていましたので、その実装方法がわからず、スレッドを
たてさせていただきました。



昔、Oracle 7.0.Xの時代にバッチ処理では、数百件ごとにcommitを出すの
が「性能向上のため」と一次流行っていました。
当時に作成されたPL/SQL,Pro*C,Pro*COBOLなどで作成されたバッチ処理では
未だに遺物(笑)として継承されているものもあります。

でも、HDD,メモリも安価、高容量となり、さらに10gでは処理性能が格段に
向上しました。
ですから、今後新規に作成するアプリケーションでは、たとえバッチ処理と
しても、全件更新後(数百万件でも)にcommitする方が、安定稼働を目指すの
なら、良いのではありませんか?
# 少なくとも、私は、そう考えています。
NAL-6295
ぬし
会議室デビュー日: 2003/01/26
投稿数: 966
お住まい・勤務地: 東京
投稿日時: 2007-05-22 10:58
NAL-6295です。

引用:

Jittaさんの書き込み (2007-05-22 06:23) より:
複数回コミットするという用件は、今まで経験したことがないのですが、複数回 BeginTransaction しなきゃいけないのかなぁ?

Dispose も忘れずに。




BeginTransactionとCommit/Rollbackは1対1なので、複数回行う必要があります。



[ メッセージ編集済み 編集者: NAL-6295 編集日時 2007-05-22 10:58 ]
よっしー
大ベテラン
会議室デビュー日: 2007/05/17
投稿数: 143
投稿日時: 2007-05-22 12:09
引用:

未記入さんの書き込み (2007-05-20 12:10) より:
・1レコード読み取り→SQL→コミットを10万回繰り返す
・1レコード読み取り→SQLを10万回繰り返し、最後に一発コミット
上記の2点はスレッドを立てる前に実装でき、検証もできていました。
しかし性能を向上させるためには、コミット間隔を50〜100件にするのが
自明の理だと思っていましたので、その実装方法がわからず、スレッドを
たてさせていただきました。
お願い致します。


実際のところ、コミット間隔を50〜100件にしてどれ位性能が上がったのでしょうか?
今後の参考までに教えてくださいますか?
性能って、処理時間のことですよね?
はにまる
ぬし
会議室デビュー日: 2003/12/19
投稿数: 969
お住まい・勤務地: 誤字脱字の国
投稿日時: 2007-05-22 22:28
スレぬしの質問から外れていますがトランザクションの話について、

業務設計者の視点として、数百万件のファイルを取得する設計を提示した段階で性能要件やシステム連携の設計が全く考えられていないと判断するよ。

またDB管理者の視点としては、rollbackされる事を考えれば、数百万件のデータをDBのトランザクションで整合性を保とうとする設計は理解できない。

視点を一つ落として開発者の視点で考えれば、CSV取込で取得ファイルの単位とトランザクションの処理単位は、CSVファイルの取込み形式に依存するんじゃぁないの。例えば、CSVファイルに1レコードでもエラーがあれば全レコード破棄とする仕様であればトランザクション処理が必要だけど、正常レコードのみを取得し異常レコードはエラーファイルに吐出す仕様ならばトランザクション処理はいらいないよね。

システムレベルで、安易にトランザクション処理に頼るシステムは稚拙だと思う。
トランザクション処理は極力最小になるように設計するのが定石だと習ってきたんだけど
最近の流行りは違うの?
よっしー
大ベテラン
会議室デビュー日: 2007/05/17
投稿数: 143
投稿日時: 2007-05-22 23:05
だから、

引用:

よっしーさんの書き込み (2007-05-21 14:00) より:
もしかして、要件的にトランザクション管理がいらないのでは?

BeginTransactionしなければ良いのでは?



こう書いたのですが
ラフィン
ぬし
会議室デビュー日: 2002/05/23
投稿数: 809
お住まい・勤務地: 外野
投稿日時: 2007-05-23 00:05
 要件や仕様を疑って意味があるケースなのかなあ?

 「自明の理」に反するのに、何で10万回コミットや10万件一括コミットが検証までできてんの?
 1件ずつ10万回コミットができているのに100件ずつ1000回コミットができないのは、「コーディングに関してそれぞれ異なる制約が設定されている」以外に何か理由はあるのかなあ?

引用:

未記入さんの書き込み (2007-05-20 12:10) より:

・1レコード読み取り→SQL→コミットを10万回繰り返す
・1レコード読み取り→SQLを10万回繰り返し、最後に一発コミット
上記の2点はスレッドを立てる前に実装でき、検証もできていました。

片桐 継
会議室デビュー日: 2007/05/16
投稿数: 14
お住まい・勤務地: 東京
投稿日時: 2007-05-23 00:17
今まさに、MAX400万件のCSVファイルを一括でデータベースに登録するというトンデモ処理を作っているところなんですが……

ファイルデータの全件取り込み保持を前提した場合でいうと、サーバーのスペックが複数CPUでHDDも大きくてメモリ大きいなら、結局、コミットを数回発行して分割で入れようが、一回コミット勝負で入れようが、パフォーマンスは対して変わりません。

どちらかというと、その処理を行う環境側、トランザクションログ領域の設定とチューニングに依存すると考えたほうが「どうコミットを行うのが理想か」の答えを導き出す鍵になるかと思うんですが。

プログラミングで言うなら、1000件程度なら一発トランザクションで十分じゃないかなぁ……と思いますけどね。

ですので、

DBに対してconnectionオブジェクト生成
connectionオープン
connectionオブジェクトからtransactionオブジェクト生成してusingで開始(end usingで自動disposeなので楽)
tryステートメント開始
connectionオブジェクトからcommandオブジェクト生成
commandオブジェクトにtransactionオブジェクトを設定
commandオブジェクトにSQL設定
commandオブジェクト実行
catchでロールバック
finallyでコミット
end using で終了
connectionクローズ

こちらはSQL-ServerがメインDBだったのでOracleの場合のオブジェクトの使い方は不明なので細かい部分は異なっているかもしれませんが、全体フローはこんな感じかなぁ、と。
_________________
片桐 継(Tugu Katagiri)@わんくま同盟
http://blogs.wankuma.com/esten

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