質問
次のコードは、単純な挿入コマンドを実行します。 (2,000行を挿入するために)2,000回連続して呼び出された場合、message =" System Resources Exceeded"のOleDbException;スローされます。リソースを解放するために他にすべきことはありますか?
using (OleDbConnection conn = new OleDbConnection(connectionString))
using (OleDbCommand cmd = new OleDbCommand(commandText, conn))
{
conn.Open();
cmd.ExecuteNonQuery();
}
解決
システムリソース超過エラーは、マネージコードからではなく、データベース(JET?)を強制終了したことによるものです
多くの接続への道、高速化への道を開いています...
ヒント:
- 単一のコマンドごとに新しい接続を開かずにラウンドトリップを回避し、単一の接続を使用して挿入を実行します。
- データベース接続プーリングが機能していることを確認します(OLEDB接続で機能するかどうかはわかりません)。
- より最適化された方法でデータを挿入することを検討してください。
これを試してみましたか
using (OleDBConnection conn = new OleDBConnection(connstr))
{
while (IHaveData)
{
using (OldDBCommand cmd = new OldDBCommand())
{
cmd.Connection = conn;
cmd.ExecuteScalar();
}
}
}
他のヒント
このコードを例外なしでAccess 2007データベースでテストしました(最大13000の挿入を行いました)。
しかし、私が気づいたのは、毎回接続を作成しているため、非常に遅いことです。 " using(connection)"ループの外側では、はるかに高速になります。
上記(データベースへの接続は1回のみ)に加えて、接続を閉じて破棄していることを確認したいと思います。 C#のほとんどのオブジェクトはメモリで管理されているため、接続とストリームには常にこの豪華さがありません。したがって、このようなオブジェクトが破棄されない場合、クリーンアップが保証されません。これには、プログラムの存続期間中、その接続を開いたままにするという追加の効果があります。
また、可能であれば、トランザクションの使用を検討します。このコードを何に使用しているのかわかりませんが、OleDbTransactionsはデータベースに多くの行を挿入および更新するときに役立ちます。
詳細についてはわかりませんが、同様の問題に遭遇しました。 IISでAccessデータベースを利用して、クライアントにサービスを提供しています。クライアントはあまり多くありませんが、1つのセッション中に多くの接続が開かれたり閉じられたりします。約1週間の作業の後、同じエラーを受け取り、すべての接続試行が失敗します。問題を修正するには、ワーカープロセスを再起動するだけでした。
調査の結果、(もちろん)この環境ではAccessがうまく機能しないことがわかりました。リソースは正しく解放されず、時間の経過とともに実行可能ファイルが不足します。この問題を解決するために、Oracleデータベースに移行します。これで問題が解決しない場合は、調査結果の最新情報をお届けします。
作成されたConnectionおよびCommandオブジェクトを破棄していないため、これが発生している可能性があります。オブジェクトは常に最後に廃棄してください。
OledbCommand.Dispose();