1

私は.NET 3.5でカスタマイズされたデータインポート実行可能ファイルを持っています.SqlBulkCopyは基本的に大量のデータをより高速に挿入します。このアプリは基本的に、入力ファイルを取得し、データを処理して SQL Server 2000 に一括アップロードします。このアプリは、SQL 2008 データベース環境でアプリを構築していたコンサルタントによって作成されました。そのenvの違いがこれを引き起こしているでしょうか?SQL 2000 には、BulkCopy のベースとなっている bcp ユーティリティがあります。そのため、これを実行すると、デッドロック エラーが発生しました。

エラーの詳細: トランザクション (プロセス ID 58) は、別のプロセスとのロック リソースでデッドロックされ、デッドロックの犠牲者として選択されました。トランザクションを再実行します。

私はそれを解決しようとする多くの方法を試しました。接続文字列変数 MultipleActiveResultSets=true を一時的に設定するなど、理想的ではありませんが、それでもデッドロック エラーが発生します。また、接続タイムアウトの問題ではないことも確認しました。

これが関数です。何かアドバイス?

/// <summary>
    /// Bulks the insert.
    /// </summary>
    public void BulkInsert(string destinationTableName, DataTable dataTable)
    {
        SqlBulkCopy bulkCopy;

        if (this.Transaction != null)
        {
            bulkCopy = new SqlBulkCopy
                (
                    this.Connection,
                    SqlBulkCopyOptions.TableLock,
                    this.Transaction
                );
        }
        else
        {
            bulkCopy = new SqlBulkCopy
                (
                    this.Connection.ConnectionString,
                    SqlBulkCopyOptions.TableLock | SqlBulkCopyOptions.UseInternalTransaction
                );
        }

        bulkCopy.ColumnMappings.Add("FeeScheduleID", "FeeScheduleID");
        bulkCopy.ColumnMappings.Add("ProcedureID", "ProcedureID");
        bulkCopy.ColumnMappings.Add("AltCode", "AltCode");
        bulkCopy.ColumnMappings.Add("AltDescription", "AltDescription");
        bulkCopy.ColumnMappings.Add("Fee", "Fee");
        bulkCopy.ColumnMappings.Add("Discount", "Discount");
        bulkCopy.ColumnMappings.Add("Comment", "Comment");
        bulkCopy.ColumnMappings.Add("Description", "Description");


        bulkCopy.BatchSize = dataTable.Rows.Count;
        bulkCopy.DestinationTableName = destinationTableName;
        bulkCopy.WriteToServer(dataTable);

        bulkCopy = null;
    }
4

4 に答える 4

0

私はかなり定期的に BCP を使用していますが、BatchSize が通常の値である 1000 以外に設定されているケースを見たことがありません。

このフィールドは、コードに示されているように行数全体を表すことを意図したものではなく、コピー中にサーバーに送信される管理可能なデータ チャンク (IP パケット サイズのようなもの) を表すことを目的としています。

テーブル全体ではなく、この値を 1000 に変更してみてください。

SQL Enterprise Manager または SQL Management Studio (クライアント ツールのバージョンによって異なります) のプロセス/ロック マネージャー ペインを見て、プロセスがロックに関して何を行っているかを確認することもできます。

于 2010-05-12T22:33:42.480 に答える
0

私は最終的に、アプリケーションをテストするために、本番データベース (最大 50 ギグ) のローカル コピーを取得することができました。ロック解除は厳密には環境の問題であることがわかりました。ありがとうございます。

于 2010-05-13T18:15:25.527 に答える
0

複数のアクティブな結果セットは挿入には関係ありません。後で追加されたため、SQL Server 2000 でサポートされているとは思えません。

SQL Server 2000 には、それ以降のバージョンほど洗練されたロック エスカレーションがありません。コンサルタントは宛先テーブルで BCP 以外のワークロードを持っていないと仮定しますが、アプリケーションは宛先テーブルで一括挿入以外のアクティビティを行います。

最初にステージング テーブルに一括挿入を行い (そこでデッドロックが発生する可能性はありません)、次にネイティブ SQL SP で (おそらく多くの小さなバッチで) 可能な限り効率的な挿入/更新クエリを実行することを検討します。

于 2010-05-13T04:05:36.260 に答える
0

これらの挿入は同時に行われていますか? クラスター化されたインデックスを持つテーブルで、TABLOCK ヒントを使用して同時挿入を行う場合、SqlBulkCopy には既知の問題があります。デッドロックが発生します。以下を参照してください。

http://msdn.microsoft.com/en-us/library/ms186341(SQL.90).aspx

于 2010-05-12T22:43:59.353 に答える