TABLOCK vs TABLOCKX


¿Cuál es la diferencia entre TABLOCK y TABLOCKX http://msdn.microsoft.com/en-us/library/ms187373.aspx los estados que TABLOCK es un bloqueo compartido, mientras que TABLOCKX es un bloqueo exclusivo. ¿Es el primero quizás solo un bloqueo de índice? ¿Y cuál es el concepto de compartir una cerradura?

Author: Carlo V. Dango, 2011-02-24

3 answers

Gran diferencia, TABLOCK intentará agarrar bloqueos "compartidos", y TABLOCKX bloqueos exclusivos.

Si estás en una transacción y tomas un bloqueo exclusivo en una mesa, POR EJEMPLO:

SELECT 1 FROM TABLE WITH (TABLOCKX)

Ningún otro proceso será capaz de agarrar cualquier bloqueos en la tabla, lo que significa todas las consultas que intenten hablar con la tabla serán bloqueadas hasta que la transacción se confirme.

TABLOCK solo agarra un bloqueo compartido, los bloqueos compartidos se liberan después de que se se ejecuta si el aislamiento de la transacción es READ COMMITTED (predeterminado). Si su nivel de aislamiento es mayor, por ejemplo: SERIALIZABLE, los bloqueos compartidos se mantienen hasta el final de una transacción.


Los bloqueos compartidos son, hmmm, compartidos. Lo que significa que 2 transacciones pueden leer los datos de la tabla al mismo tiempo si ambas tienen una S o UN bloqueo en la tabla (a través de TABLOCK). Sin embargo, si transaction A tiene un bloqueo compartido en una tabla, transaction B no podrá agarrar un bloqueo exclusivo hasta que todos los bloqueos compartidos sean lanzar. Lea acerca de qué bloqueos son compatibles con qué en msdn.


Ambas sugerencias hacen que la base de datos omita la toma de bloqueos más granulares (como bloqueos de nivel de fila o página). En principio, los bloqueos más granulares le permiten una mejor concurrencia. Así, por ejemplo, una transacción podría estar actualizando la fila 100 en su tabla y otra fila 1000, al mismo tiempo de dos transacciones (se vuelve complicado con los bloqueos de página, pero omitamos eso).

En general, los bloqueos granulares son lo que desea, pero a veces es posible que desee reducir la concurrencia de bases de datos para aumentar el rendimiento de una operación en particular y eliminar la posibilidad de bloqueos.

En general, no usaría TABLOCK o TABLOCKX a menos que lo necesite absolutamente para algún caso de borde.

 84
Author: Sam Saffron,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-02-25 05:59:03

Un viejo artículo sobre mssqlcity intenta explicar los tipos de bloqueos:

Los bloqueos compartidos se utilizan para operaciones que no cambian ni actualizan datos, como una instrucción SELECT.

Los bloqueos de actualización se utilizan cuando SQL Server tiene la intención de modificar una página, y luego promueve el bloqueo de página de actualización a un bloqueo de página exclusivo antes de realizar los cambios.

Los bloqueos exclusivos se utilizan para las operaciones de modificación de datos, como ACTUALIZAR, INSERTAR o ELIMINAR.

Lo que no discute es Intent (que básicamente es un modificador para estos tipos de bloqueo). Los bloqueos de intención (Compartidos / Exclusivos) son bloqueos mantenidos en un nivel más alto que el bloqueo real. Así, por ejemplo, si su transacción tiene un bloqueo X en una fila, también tendrá un bloqueo IX en el nivel de la tabla (que impide que otras transacciones intenten obtener un bloqueo incompatible en un nivel superior de la tabla (por ejemplo, un bloqueo de modificación de esquema) hasta que su transacción se complete o ruede volver).


El concepto de "compartir" un bloqueo es bastante sencillo: varias transacciones pueden tener un bloqueo compartido para el mismo recurso, mientras que solo una transacción puede tener un bloqueo Exclusivo, y un bloqueo Exclusivo impide que cualquier transacción obtenga o mantenga un bloqueo compartido.

 4
Author: Damien_The_Unbeliever,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-03-08 12:56:19

Este es más un ejemplo donde TABLOCK no funcionó para mí y TABLOCKX lo hizo.

Tengo 2 sesiones, que ambas usan el nivel de aislamiento predeterminado (LECTURA CONFIRMADA):

La sesión 1 es una transacción explícita que copiará datos de un servidor vinculado a un conjunto de tablas en una base de datos, y tarda unos segundos en ejecutarse. [Ejemplo, elimina Preguntas] La sesión 2 es una instrucción insert, que simplemente inserta filas en una tabla en la que la sesión 1 no realiza cambios. [Ejemplo, inserta Respuesta].

(En la práctica hay varias sesiones insertando varios registros en la tabla, simultáneamente, mientras que la Sesión 1 está ejecutando su transacción).

La sesión 1 tiene que consultar la tabla en la que se inserta la sesión 2 porque no puede eliminar registros que dependen de las entradas que se agregaron por la Sesión 2. [Ejemplo: Eliminar preguntas que no han sido respondidas].

Entonces, mientras la Sesión 1 se ejecuta y la Sesión 2 intenta insertar, la Sesión 2 pierde en un punto muerto cada tiempo.

Entonces, una instrucción delete en la Sesión 1 podría verse algo como esto: DELETE tblA FROM tblQ LEFT JOIN tblX on ... IZQUIERDA UNIRSE A tblA a EN tblQ.Qid = tblA.Qid DONDE ... a. QId ES NULO y ...

El punto muerto parece ser causado por la disputa entre consultar tblA durante la sesión 2, [3, 4, 5, ..., n] tratar de insertar en tblA.

En mi caso podría cambiar el nivel de aislamiento de la transacción de la Sesión 1 para ser SERIALIZABLE. Cuando hice esto: El administrador de transacciones tiene deshabilitado su soporte para transacciones remotas/de red.

Por lo tanto, podría seguir las instrucciones en la respuesta aceptada aquí para evitarlo: El administrador de transacciones ha desactivado su soporte para transacciones remotas/de red

Pero a) No me sentía cómodo con cambiar el nivel de aislamiento a SERIALIZABLE en primer lugar - supuestamente degrada el rendimiento y puede tener otras consecuencias que no he considerado, b) no entendí por qué hacer esto de repente causó la transacción para tener un problema de trabajo a través de servidores vinculados, y c) no sé qué posibles agujeros que podría estar abriendo al habilitar el acceso a la red.

Parecía haber solo 6 consultas dentro de una transacción muy grande que están causando el problema.

Entonces, leí sobre TABLOCK y TabLOCKX.

No estaba muy claro en las diferencias, y no sabía si cualquiera de las dos funcionaría. Pero parecía que lo haría. Primero probé TABLOCK y no parecía hacer ninguna diferencia. El las sesiones en competencia generaron los mismos puntos muertos. Luego probé TABLOCKX, y no más bloqueos.

Entonces, en seis lugares, todo lo que necesitaba hacer era agregar un CON (TABLOCKX).

Entonces, una instrucción delete en la Sesión 1 podría verse algo como esto: DELETE tblA FROM tblQ q LEFT JOIN tblX x on ... IZQUIERDA UNIRSE A tblA a CON (TABLOCKX) EN tblQ.Qid = tblA.Qid DONDE ... a. QId ES NULO y ...

 2
Author: John,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 11:47:31