¿Una consulta de selección simple adquiere bloqueos?

14

Soy muy nuevo en SQL Server, y me gustaría entender si la siguiente selectdeclaración , muy simple , tomaría algún candado.

Select * from Student;

Considere el caso en el que la declaración no se estaría ejecutando dentro de un begin tranbloque.

Nuevo desarrollador
fuente
1
Esta es una pregunta mucho más complicada de lo que piensas. La respuesta depende de muchas cosas (¿cuál es el nivel de aislamiento de la transacción de la sesión? ¿Se activa el aislamiento de la instantánea confirmada de lectura? ¿El índice escaneado tiene opciones configuradas para evitar bloqueos de fila o página?) E incluso puede cambiar durante la ejecución de la instrucción (cuántos las filas están en la tabla? ¿está dividida la tabla?). Aquí hay un buen punto para comenzar a leer.
Jon Seigel

Respuestas:

5

Sí, toma un bloqueo compartido en las filas que lee de forma predeterminada (también toma un bloqueo de intención compartida en todas las páginas del índice agrupado que leerá), esto se hace para evitar lecturas sucias. Sin embargo, hay formas de evitar esto (SQL Server tiene la sugerencia nolock). Si la declaración no está en un COMIENZO TRAN el bloqueo se libera después de que se haya ejecutado la instrucción SELECT.

Encuentra más información aquí:

http://msdn.microsoft.com/en-us/library/ms184286(v=sql.105).aspx http://www.sqlteam.com/article/introduction-to-locking-in-sql-server

Libre de arrugas
fuente
Además, también puede establecer el nivel de aislamiento de la transacción para leer sin confirmar.
Zane
1
Entonces, si SELECT lee diez filas, ¿se mantienen los diez bloqueos compartidos hasta que se hayan leído las diez filas o se han adquirido y liberado por fila?
Ian Warburton
26

Me gustaría entender si la siguiente declaración de selección muy simple tomaría algún candado

Es un error común pensar que una SELECTconsulta que se ejecuta en el READ COMMITTEDnivel de aislamiento de transacción predeterminado siempre tomará bloqueos compartidos para evitar lecturas sucias.

SQL Server puede evitar tomar bloqueos de nivel de fila compartidos cuando no hay peligro de leer datos no confirmados sin ellos (aunque todavía se toman bloqueos de Intent-Shared (IS) de nivel superior).

Incluso si se toman bloqueos de fila compartidos (tal vez porque otra transacción concurrente ha modificado la página en la que se encuentra la fila), se pueden liberar mucho antes de SELECTque se complete la declaración.

En la mayoría de los casos, la fila se 'desbloquea' justo antes de que el servidor procese la siguiente fila. Hay circunstancias en las que los bloqueos compartidos tomados en el nivel de aislamiento predeterminado se mantienen hasta el final de la declaración actual, pero no hasta el final de la transacción .

Anular el nivel de aislamiento actual con la NOLOCKsugerencia de tabla es casi siempre una mala idea .

El bloqueo es un detalle de implementación. SQL Server toma bloqueos cuando es necesario para garantizar que cumpla con las garantías semánticas proporcionadas por el nivel de aislamiento actual . Ciertamente, hay momentos en los que es útil saber un poco sobre por qué se toman las cerraduras, pero intentar predecirlas es a menudo contraproducente.

SQL Server proporciona una amplia variedad de niveles de aislamiento; elija el que ofrezca las garantías y los comportamientos que necesitan sus consumidores de datos.

Paul White 9
fuente