Como se esperaba
-
SELECT con ORDER BY, sin ROWLOCK, sin índice tendrá un bloqueo de tabla debido a un escaneo/clasificación intermedia para calcular TOP 2. Entonces, la segunda sesión omite toda la tabla debido a READPAST
-
El SELECCIONAR sin el ORDEN POR es simplemente elegir 2 filas, que resultan estar en orden de inserción (pura coincidencia, no hay un orden implícito). El hecho de que estas 2 filas estén bloqueadas hace que la segunda sesión salte a las siguientes filas no bloqueadas.
SQL Server intenta mantener los bloqueos lo más detallados posible, pero el escaneo significa un bloqueo de tabla. Ahora, esto normalmente no marcaría la diferencia (sería un bloqueo de lectura compartido), pero también tiene UPDLOCK, lo que significa una tabla bloqueada exclusivamente
Entonces, necesitas ambos
- 3 sugerencias en las consultas SELECT (ROWLOCK, UPDLOCK, READPAST) para controlar la granularidad, el aislamiento y la concurrencia.
El uso de ROWLOCK solo causará un bloqueo exclusivo en cada fila para escanear/ordenar. - un índice en
Value
INCLUIRTestID
para hacer el SELECT eficiente. Un índice solo arreglará probablemente la concurrencia, pero no estará garantizado.
En una de sus preguntas anteriores, vinculé mi respuesta (en un comentario) a Condición de carrera de cola de proceso de SQL Server donde tengo las 3 sugerencias de bloqueo