- PR -

コミット間隔

投稿者投稿内容
未記入
常連さん
会議室デビュー日: 2007/05/01
投稿数: 35
投稿日時: 2007-05-19 01:39
お世話になっております。

VB.NETでCSVファイル(1000件程度)からレコードを1件ずつ読み取り、
DBへ出力させるコンソールアプリケーションを作成しています。

コミット間隔をある一定間隔(100件程度)にしたい場合、どのように実装すればよいでしょうか?

現在は下記の状況です。
(最後に一発コミットです。とりあえずうまくいきます)

Dim cnn As New OracleConnection(”接続文字列”)
Dim trn As OracleTransaction = cnn.BeginTransaction
Dim cmd As New OracleCommand
cmd.Connection = cnn
Dim sql As String = "INSERT文"
cmd.Transaction = trn

Try
ループ処理(CSVの全レコードを抽出するまで)
{
cmd.ExecuteNonQuery()
(★)
}
trn.Commit()
Catch(ex)
trn.RollBack()
Finally
cnn.Close()
End Try

上記の(★)にcmd.ExecuteNonQuery()を実行した回数を保持する変数を
持たせ、100回実行した場合コミットしようとしました。
しかし、コミット後のトランザクションの生成がどうしても上手くいかず(よくわからず)、困っております。

よい実装方法(解決方法)ありましたら教えて頂けないでしょうか?

よろしくお願いします。
甕星
ぬし
会議室デビュー日: 2003/03/07
投稿数: 1185
お住まい・勤務地: 湖の見える丘の上
投稿日時: 2007-05-19 06:32
[quote]
Dim trn As OracleTransaction = cnn.BeginTransaction
[quote]
良い方法も何も、上記の一行をループの中で行うだけですよ。
未記入
常連さん
会議室デビュー日: 2007/05/01
投稿数: 35
投稿日時: 2007-05-19 09:48
ご回答ありがとうございます。

その方法は試みましたが、下記のエラーがでます。
「並列トランザクションはサポートされていません。」

OracleTransactionって複数生成できるのですか?

そもそも私の考え方がおかしい?

よろしくお願いします。



かるあ
ぬし
会議室デビュー日: 2003/11/16
投稿数: 1190
お住まい・勤務地: センガワ→ムサシノ
投稿日時: 2007-05-19 10:46
引用:

未記入さんの書き込み (2007-05-19 01:39) より:

上記の(★)にcmd.ExecuteNonQuery()を実行した回数を保持する変数を
持たせ、100回実行した場合コミットしようとしました。
しかし、コミット後のトランザクションの生成がどうしても上手くいかず(よくわからず)、困っております。


こっちっていったいどのように実装したんだろう。
実装例と発生したエラーの詳細って出すことができますか?
_________________
かるあ のメモスニペット
rain
ぬし
会議室デビュー日: 2006/10/19
投稿数: 549
投稿日時: 2007-05-19 11:04
こんにちは。

引用:


現在は下記の状況です。
(最後に一発コミットです。とりあえずうまくいきます)




素人の浅知恵ですが、その処理へ渡すクエリを
処理の外で100個単位に分けてから呼び出すってのはだめっすか?
ラフィン
ぬし
会議室デビュー日: 2002/05/23
投稿数: 809
お住まい・勤務地: 外野
投稿日時: 2007-05-19 11:12
引用:

未記入さんの書き込み (2007-05-19 09:48) より:

その方法は試みましたが、下記のエラーがでます。
「並列トランザクションはサポートされていません。」

OracleTransactionって複数生成できるのですか?


 BeginTransaction -> Commit
 を繰り返すつもりが、どこかが
 BeginTransaction -> BeginTransaction
 になっているとか?
 (ループの手前とループ1回目の先頭で BeginTransaction ?)
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2007-05-19 13:05
引用:

未記入さんの書き込み (2007-05-19 01:39) より:

コミット間隔をある一定間隔(100件程度)にしたい場合、どのように実装すればよいでしょうか?


そもそも一定間隔にしたい理由は何でしょうか?
障害発生時の '不整合' を視野に入れた仕様は存在するのでしょうか?

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
未記入
常連さん
会議室デビュー日: 2007/05/01
投稿数: 35
投稿日時: 2007-05-19 19:23
>こっちっていったいどのように実装したんだろう。
>実装例と発生したエラーの詳細って出すことができますか?

かるあさん、ご質問ありがとうございます。

エラーとはコンパイルエラーのことです。
実装しようとしていたイメージは下記です。

Dim cnn As New OracleConnection(”接続文字列”)
Dim trn As OracleTransaction = cnn.BeginTransaction
Dim cmd As New OracleCommand
cmd.Connection = cnn
Dim sql As String = "INSERT文"
cmd.Transaction = trn

Try
ループ処理(CSVの全レコードを抽出するまで)
{
cmd.ExecuteNonQuery()
(★)
cnt = cnt + 1
If cnt = 100 then
trn.Commit()
Dim trn As OracleTransaction = cnn.BeginTransaction
cmd.Transaction = trn
End If
}
If cnt <> 100 then
trn.Commit()
End If
Catch(ex)
trn.RollBack()
Finally
cnn.Close()
End Try

ループ処理の中の
Dim trn As OracleTransaction = cnn.BeginTransactionでコンパイルエラーです。
あたりまえか。。。
しかし、OracleTransactionの別オブジェクトを生成すれば(trnではなく、trn1とか)
実行時に「並列トランザクションはサポートされていません。」
となります。
どうすればよいのやら。。。
よろしくお願い致します。

>素人の浅知恵ですが、その処理へ渡すクエリを
>処理の外で100個単位に分けてから呼び出すってのはだめっすか?
rainさん、ご回答ありがとうございます。

申し訳ありません。
理解ができないので、もう少しわかりやすく説明していただければと思います。
よろしくお願い致します。

> BeginTransaction -> Commit
> を繰り返すつもりが、どこかが
> BeginTransaction -> BeginTransaction
> になっているとか?
> (ループの手前とループ1回目の先頭で BeginTransaction ?)
ラフィンさん、ご回答ありがとうございます。

BeginTransaction -> Commitを繰り返したいのではありません。
BeginTransactionを実行し、その後のSQL処理を繰り返し、
100回単位でCommitを行いたいのです。
CSVのレコード件数が250件存在し、230件目に不整合なデータが存在する場合、
データベースには1件〜200件のデータが出力され、201〜250件目のデータは
出力されないイメージです。
よろしくお願い致します。


>そもそも一定間隔にしたい理由は何でしょうか?
>障害発生時の '不整合' を視野に入れた仕様は存在するのでしょうか?

じゃんぬねっとさん、ご質問ありがとうございます。
一定間隔にしたい理由は、性能問題です。
CSVのレコード件数が10万件存在するとした場合、
1レコード読み取り→SQL→コミット
のサイクルを10万回繰り返すのではなく、
1レコード読み取り→SQLを100回繰り返し、1回コミット
のサイクルを1000回繰り返したほうが性能がよいと考えられるからです。
(実際試したわけではないので、保証はできませんが。。。)

>障害発生時の '不整合' を視野に入れた仕様は存在するのでしょうか?
存在しません。

よろしくお願い致します。

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