問題は、使用している分離レベルです。変更しない限り、SQL Server (および他の多くのデータベース) は、コミットされていない読み取りをブロックするモードで動作します。代わりにMVCCを使用するようにSQL Serverを変更したい(Oracleのデフォルト。MySQLとSQL Serverの両方にもあります)。問題は解決します。
SET TRANSACTION ISOLATION LEVEL (Transact-SQL)から:
コミットされた読み取り
ステートメントは、他のトランザクションによって変更されたがコミットされていないデータを読み取ることができないことを指定します。これにより、ダーティ リードが防止されます。データは、現在のトランザクション内の個々のステートメント間で他のトランザクションによって変更される可能性があり、その結果、反復不可能な読み取りまたはファントム データが発生します。このオプションは、SQL Server のデフォルトです。
READ COMMITTED の動作は、READ_COMMITTED_SNAPSHOT データベース オプションの設定によって異なります。
- READ_COMMITTED_SNAPSHOT が OFF (既定) に設定されている場合、データベース エンジンは共有ロックを使用して、現在のトランザクションが読み取り操作を実行している間、他のトランザクションが行を変更できないようにします。共有ロックは、他のトランザクションが完了するまで、ステートメントが他のトランザクションによって変更された行を読み取ることもブロックします。
共有ロックのタイプによって、いつ解放されるかが決まります。行ロックは、次の行が処理される前に解放されます。次のページが読み取られるとページ ロックが解放され、ステートメントが終了するとテーブル ロックが解放されます。
- READ_COMMITTED_SNAPSHOT が ON に設定されている場合、データベース エンジンは行のバージョン管理を使用して、ステートメントの開始時に存在していたデータのトランザクション的に一貫性のあるスナップショットを各ステートメントに提示します。ロックは、他のトランザクションによる更新からデータを保護するために使用されません。
READ_COMMITTED_SNAPSHOT データベース オプションが ON の場合、READ COMMITTEDLOCK テーブル ヒントを使用して、READ COMMITTED 分離レベルで実行されているトランザクション内の個々のステートメントの行のバージョン管理ではなく、共有ロックを要求できます。
(強調追加)
データベース構成を変更して、READ_COMMITTED_SNAPSHOT を ON にします。
また、トランザクションを可能な限り短命に保ち、バックグラウンド プロセスでトランザクションをコミットしていることを確認してください (つまり、1 時間に 10,000 の挿入を実行しています)。コミットしないと、selects が永久にブロックされるためです (既定の設定)。