SqlTransaction を使用して数千の SqlCommand を処理するとメモリ例外が発生する

StackOverflow https://stackoverflow.com//questions/11675430

質問

SQL Server 2008 Express データベースを使用して、標準の C# Windows フォーム アプリでカスタム レプリケーション関数を作成しました。これは基本的に、サブスクライバ データベースに対して実行する必要がある一連の SQL ステートメントをプルダウンします。完全なリフレッシュでは、実行する必要のある最大 200,000 個以上のステートメントが実行される可能性があります。

以下に示すように、コード ブロック内でこれらのステートメントを処理します。

using (SqlConnection connection = ConnectionManager.GetConnection())
{
     connection.Open();

     SqlTransaction transaction = connection.BeginTransaction();

     // Process 200k+ Insert/Update/Delete statements using SqlCommands

     transaction.Commit
}

私が発見したのは、アプリケーションのメモリ使用量は、最初の 30,000 ステートメントで約 40 MB でかなり安定しているということです。その後、突然約 300MB に跳ね上がったように見え、その後 OutOfMemory 例外が発生するまで増加します。

私が使用している方法は可能でしょうか。単一のトランザクション内でこれほど多くのステートメントを処理できますか?これはできるはずだと思います。もっと良い方法があれば、ぜひここに載せたいと思います。これをトランザクション対応にする必要があります。そうしないと、部分的なレプリケーションが発生してデータベースが壊れてしまいます。

ありがとう。

編集:

コンピューターを再起動した後、200k 以上の完全なレプリケーションを実行することができました。レプリケーションが完了した後、ある時点でメモリ使用量が 1.4 GB まで増加しましたが、メモリ使用量は 40 MB まで下がりました。このことから、コマンドを処理するループ内の何かがメモリの増大を引き起こしている可能性があると結論付けています。

役に立ちましたか?

解決

あなたは Disposing フォームと使い捨てコントロールを閉じる前に?

すべての Disposable オブジェクトを using ステートメントでラップします。詳細についてはここをクリックしてください


接続を何度も開いたり閉じたりせず、単一のトランザクションでデータをデータベースに送信します。詳細についてはここをクリックしてください


それでもアプリケーションが大量のメモリを保持している場合は、Red Gate Ants Memory Profiler のような Doctor が必要です。詳細を確認するにはここをクリックしてください

enter image description here


単一のトランザクション内でそれほど多くのステートメントを処理できますか?

これを行うには以下のオプションがあります...

  1. レコードを一括挿入して操作します Stored Proc.
  2. 準備する XML そして文字列を送信してください Database.
  3. 読み取り専用で送信します DataTable ストアドプロシージャを介した SQL Server 内

サンプルストアドプロシージャ

Begin Try
    Set NoCount ON
    Set XACT_Abort ON
    Begin TRan
        --Your queries
    Commit Tran

Begin Tran

Begin Catch
    Rollback Tran
End Catch

必ず Dispose 一度使用されなくなったオブジェクト。


このようにあるべきです

using (SqlConnection connection = new SqlConnection())
{
    connection.Open();
    using (SqlTransaction transaction = connection.BeginTransaction())
    {
        transaction.Commit();
    }
}

確認しましたか SqlCommand また?

using (SqlCommand cmd = new SqlCommand())
{
}
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top