0

SQL Server 2012 を使用して .NET 4.5 で Entity Framework 5 を使用しています。サード パーティのソースから大量のデータをダウンロードしてデータベースに解析する機能があります。2,500 レコードのバッチで、エンティティをダウンロードして解析し、データベースに挿入/更新します。

データベースへの挿入/更新のために、SqlBulkCopy クラスを利用しています。データベースへの挿入/更新を行っているときに、挿入/更新先のテーブルが部分的に応答していないようです。SSMS から単純な選択クエリを実行すると、いくつかのレコードがプルされ、アプリが一括挿入/更新を完了するまでハングします。データベース内のこのデータは、WCF サービスを介して複数のソースに供給されます。ソースの 1 つでデータをロードしようとすると、データベースがデータに応答しないためにタイムアウトになります。挿入/更新が完了すると、WCF サービスと SSMS クエリの両方が引き続き正常に実行されます。

これは SqlBulkCopy が原因である可能性があると考えたため、そのクラスの使用を削除し、まったく同じ結果を生成する context.SaveChanges() を呼び出しました。次に、EF を完全に排除してテストを実行し、従来の ADO.NET (SqlBulkCopy なし) を使用しましたが、すべてがうまく機能しました。SqlBulkCopy を再度接続し、EF を除外すると、終了するまでテーブルがロックされているように見えます。

したがって、ここでの犯人は EF と SqlBulkCopy の両方であると想定しています。これを回避し、引き続き EF と SqlBulkCopy を使用する方法についてのアイデアはありますか? またはこれが起こる原因は何ですか?

ここでコードの例を示す必要はないと思いますが、見たい場合はお知らせください。前もって感謝します。

4

1 に答える 1

1

取引のせいだと思います。SqlBukCopy または context.SaveChanges() を使用すると、トランザクション内で挿入が行われます。そのコードを従来の ADO.NET に置き換えたとき、挿入をトランザクションにラップしましたか?それとも、各挿入を独自の暗黙的なトランザクション内で発生させましたか?

トランザクションが保留中の場合、更新中のテーブルの一部がロックされます。十分なデータを挿入すると、テーブルまたはテーブル全体の多くのページがロックされる可能性があります (これはロック エスカレーションと呼ばれます)。

これを回避する最善の方法は、更新を小さなチャンクに分割することです。他にもいくつかのオプション (コミットされていないデータの読み取りなど) がありますが、これらには重大な欠点があり、通常は避ける必要があります。

于 2012-11-12T23:00:45.020 に答える