En su escenario, recomendaría establecer explícitamente el nivel de aislamiento en instantánea, lo que evitará que la lectura se interponga en el camino de las escrituras (inserciones y actualizaciones) al evitar bloqueos, pero esas lecturas seguirán siendo lecturas "buenas" (es decir, no datos sucios - no es lo mismo que un NOLOCK)
En general, encuentro que cuando tengo problemas de bloqueo con mis consultas, controlo manualmente el bloqueo aplicado. p.ej. Haría actualizaciones con bloqueos a nivel de fila para evitar el bloqueo a nivel de página/tabla, y establecería mis lecturas en lectura pasada (aceptando que puedo perder algunos datos, en algunos escenarios que podrían estar bien) enlace|editar|eliminar|marcar
EDITAR:combinar todos los comentarios en la respuesta
Como parte del proceso de optimización, el servidor sql evita que se confirmen lecturas en una página que sabe que no ha cambiado y recurre automáticamente a una estrategia de bloqueo menor. En su caso, el servidor sql pasa de una lectura serializable a una lectura repetible.
P:Gracias por esa información útil sobre la reducción de los niveles de aislamiento. ¿Puedes pensar en alguna razón por la que usaría Serializable IsolationLevel en primer lugar, dado que no usamos una transacción explícita para SELECT; entendimos que la transacción implícita usaría ReadCommitted?
R:De manera predeterminada, SQL Server usará Read Commmitted si ese es su nivel de aislamiento predeterminado, PERO si no especifica una estrategia de bloqueo adicional en su consulta, básicamente le está diciendo al servidor sql "haga lo que crea que es mejor, pero mi preferencia es lectura comprometida". Dado que SQL Server es libre de elegir, lo hace para optimizar la consulta. (El algoritmo de optimización en el servidor sql es muy complejo y yo mismo no lo entiendo completamente). No ejecutar explícitamente dentro de una transacción, afaik, no afecta el nivel de aislamiento que usa el servidor sql.
P:Una última cosa, ¿parece razonable que SQL Server aumente el nivel de aislamiento (y presumiblemente la cantidad de bloqueos necesarios) para optimizar la consulta? También me pregunto si la reutilización de una conexión agrupada afectaría esto si heredara el último nivel de aislamiento utilizado.
R:El servidor Sql lo hará como parte de un proceso llamado "Escalamiento de bloqueo". Desde http://support.microsoft.com/kb/323630 , cito:"Microsoft SQL Server determina dinámicamente cuándo realizar la escalada de bloqueo. Al tomar esta decisión, SQL Server tiene en cuenta la cantidad de bloqueos que se mantienen en un escaneo en particular, la cantidad de bloqueos que se mantienen en toda la transacción, y la memoria que se utiliza para los bloqueos en el sistema en su conjunto. Por lo general, el comportamiento predeterminado de SQL Server hace que la escalada de bloqueos ocurra solo en aquellos puntos en los que mejoraría el rendimiento o cuando debe reducir el exceso de memoria de bloqueo del sistema a un nivel más razonable. Sin embargo, algunos diseños de aplicaciones o consultas pueden desencadenar un escalamiento de bloqueo en un momento en que no es deseable, y el bloqueo de tabla escalado puede bloquear a otros usuarios".
Aunque la escalada de bloqueo no es exactamente lo mismo que cambiar el nivel de aislamiento bajo el que se ejecuta una consulta, esto me sorprende porque no hubiera esperado que el servidor sql tomara más bloqueos de los que permite el nivel de aislamiento predeterminado.