TABLOCK vs TABLOCKX

Qual é a diferença entre TABLOCK e TABLOCKX http://msdn.microsoft.com/en-us/library/ms187373.aspx indica que TABLOCK é um bloqueio compartilhado enquanto TABLOCKX é um bloqueio exclusivo. A primeira talvez seja apenas uma fechadura de índice? E qual é o conceito de compartilhar uma fechadura?

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

3 answers

Grande diferença, {[[0]} vai tentar agarrar Fechaduras" partilhadas", e TABLOCKX Fechaduras exclusivas.

Se estiver numa transacção e tiver uma fechadura exclusiva numa mesa, por exemplo:

SELECT 1 FROM TABLE WITH (TABLOCKX)

Nenhum outro processo será capaz de agarrar Qualquer bloqueio sobre a mesa, o que significa todas as consultas que tentarem falar com a tabela serão bloqueadas até que a transacção se comprometa.

TABLOCK só pega numa fechadura Partilhada, as fechaduras partilhadas são libertadas depois de uma declaração ser executado se o isolamento da sua transacção for READ COMMITTED (por omissão). Se o seu nível de isolamento for superior , por exemplo: SERIALIZABLE, as fechaduras partilhadas são mantidas até ao fim de uma transacção.


As fechaduras partilhadas são, hmmm, partilhadas. O que significa que duas transacções podem ler os dados da tabela ao mesmo tempo, se ambos tiverem um S ou estiverem bloqueados na tabela (via TABLOCK). No entanto, se transaction A mantiver uma fechadura partilhada numa mesa, transaction B não será capaz de agarrar uma fechadura exclusiva até que todas as fechaduras partilhadas sejam comercializar. Leia sobre quais bloqueios são compatíveis com os quais no msdn .


Ambas as dicas fazem com que o db contorne com mais bloqueios granulares (como bloqueios ao nível da linha ou da página). Em princípio, mais fechaduras granulares permitem uma melhor concorrência. Assim, por exemplo, uma transacção pode estar a actualizar a linha 100 na sua tabela e outra linha 1000, ao mesmo tempo de duas transacções (torna-se complicado com bloqueios de página, mas vamos saltar isso). Em geral, as fechaduras granulares são o que você quer, mas às vezes você pode querer reduzir db concorrência para aumentar o desempenho de uma determinada operação e eliminar a chance de bloqueios.

De um modo geral, não usaria {[[0]} ou TABLOCKX a não ser que precisasse absolutamente dele para algum caso extremo.

 84
Author: Sam Saffron, 2011-02-25 05:59:03

Um artigo bastante antigo sobre mssqlcity tenta explicar os tipos de fechaduras:

Os bloqueios partilhados são usados para operações que não alteram ou actualizam dados, como uma instrução SELECT.

Os bloqueios de actualização são usados quando o servidor SQL pretende modificar uma página, e mais tarde promove o bloqueio de actualização da página para um bloqueio exclusivo da página antes de efectuar as alterações.

São utilizados bloqueios exclusivos para as operações de modificação de dados, tais como actualizar, inserir, ou apagar.

O que não se discute é a intenção (que basicamente é um modificador para estes tipos de bloqueio). As fechaduras de intenção (compartilhadas / exclusivas) são bloqueios mantidos em um nível superior ao real. Assim, por exemplo, se sua transação tem um X lock em uma linha, ele também terá um IX lock ao nível da tabela (o que impede outras transações de tentar obter um lock incompatível em um nível mais elevado na tabela (por exemplo, um schema modification lock) até que sua transação completa ou rolls volta).


O conceito de" partilhar " uma fechadura é bastante simples - várias transacções podem ter uma fechadura partilhada para o mesmo recurso, enquanto que apenas uma única transacção pode ter uma fechadura exclusiva, e uma fechadura exclusiva impede qualquer transacção de obter ou manter uma fechadura Partilhada.

 4
Author: Damien_The_Unbeliever, 2014-03-08 12:56:19
Este é mais um exemplo em que a TABLOCK não trabalhava para mim e a TABLOCKX trabalhava.

Tenho 2 sessões, que ambas usam o nível de isolamento predefinido (ready COMMITTED):

A Sessão 1 é uma transacção explícita que irá copiar dados de um servidor ligado para um conjunto de tabelas numa base de dados, e leva alguns segundos a correr. [Exemplo, ele apaga perguntas] Sessão 2 é uma declaração de inserção, que simplesmente insere linhas em uma tabela que a sessão 1 não faz alterações. [Exemplo, it insere Respostas].

(na prática, existem várias sessões a inserir vários registos na tabela, simultaneamente, enquanto a sessão 1 está a executar a sua transacção).

A Sessão 1 tem de consultar a tabela em que a sessão 2 insere porque não pode apagar registos que dependem de entradas que foram adicionadas pela sessão 2. [Exemplo: excluir perguntas que não foram respondidas].

Por isso, enquanto a sessão 1 está a ser executada e a sessão 2 tenta inserir, a sessão 2 perde num impasse a cada tempo.

Então, uma declaração de eliminação na sessão 1 pode parecer-se com isto.: Apagar o tblA do TBLQ ligar à esquerda o tblX ligado ... Esquerda, junta-te ao tblq.Qid = tblA.Qid ONDE ... A. QId é nulo e ... O impasse parece ser causado pela disputa entre questionar o tblA durante a sessão. 2, [3, 4, 5, ..., n] tente inserir no tblA. No meu caso, posso alterar o nível de isolamento da transacção da Sessão 1 para ser serializável. Quando eu fiz isso: o gerente de transação tem desactivou o seu suporte para transacções à distância/rede.

Então, eu poderia seguir as instruções na resposta aceite aqui para contorná-la: o Gestor de transacções desactivou o seu suporte para transacções remotas / de Rede

Mas a) eu não estava confortável em mudar o nível de isolamento para serializável em primeiro lugar - supostamente degrada o desempenho e pode ter outras consequências que eu não considerei, b) não entendi porque fazer isso de repente causou a transação para ter um problema trabalhando em servidores ligados, e c) não sabe que possíveis buracos eu poderia estar abrindo ao permitir o acesso à rede. Parecia haver apenas 6 consultas dentro de uma transação muito grande que estão causando o problema. Então, li sobre a mesa e a mesa. Não fui muito claro sobre as diferenças e não sabia se alguma delas funcionaria. Mas parecia que sim. Primeiro experimentei a mesa e não pareceu fazer diferença. O as sessões concorrentes geraram os mesmos deadlocks. Depois experimentei TABLOCKX, e acabaram-se os deadlocks. Então, em seis lugares, tudo que eu precisava fazer era adicionar um com (TABLOCKX). Então, uma declaração de eliminação na sessão 1 pode parecer-se com isto.: Apagar o tblA do TBLQ q à esquerda juntar o tblX x ligado ... Juntar à esquerda o tblA a com (TABLOCKX) no tblQ.Qid = tblA.Qid ONDE ... A. QId é nulo e ...
 2
Author: John, 2017-05-23 11:47:31