Pergunta

Estamos usando um banco de dados SQL Server 2005 (sem versão de linha) com uma enorme declaração de seleção, e estamos vendo isso bloquear outras declarações de correr (visto usando sp_who2). Eu não sabia que instruções SELECT podem causar o bloqueio -? Não há nada que eu possa fazer para mitigar este

Foi útil?

Solução

SELECIONAR pode bloquear atualizações. Um modelo de dados projetado corretamente e consulta só irá causar bloqueio mínima e não ser um problema. O 'normal' com sugestão NOLOCK é quase sempre a resposta errada. A resposta adequada é ajustar sua consulta para que ele faz enormes mesas não digitalização.

Se a consulta for untunable então você deve primeiro considerar nível de isolamento de instantâneo , segundo você deve considerar o uso banco de dados e última opção deve ser DIRTY LÊ (e é melhor para mudar a nível de isolamento em vez de usar a dica NOLOCK). Note-se que leituras sujas, como o nome indica claramente, retornará dados inconsistentes (por exemplo. A folha total pode ser desequilibrado).

Outras dicas

A partir documentação :

fechaduras Shared (S) permitir transações concorrentes para ler (SELECT) um recurso sob controle de simultaneidade pessimista. Para mais informações, consulte Types of Concurrency Control. Sem outras transações pode modificar os dados enquanto existem bloqueios shared (S) no recurso. fechaduras Shared (S) sobre um recurso são liberados tão logo os concluída operação de leitura, a menos que o nível de isolamento transação está definido para leitura repetida ou superior, ou uma dica de bloqueio é usado para manter os bloqueios shared (S) para a duração da transação.

A shared lock é compatível com outro bloqueio compartilhado ou um bloqueio de atualização, mas não com um bloqueio exlusive.

Isso significa que suas consultas SELECT irão bloquear UPDATE e INSERT consultas e vice-versa.

A SELECT consulta irá colocar um bloqueio compartilhado temporária quando se lê um bloco de valores da tabela, e removê-lo quando terminar de ler.

Para o tempo existe o bloqueio, você não será capaz de fazer qualquer coisa com os dados na área bloqueada.

Duas consultas SELECT nunca vai bloquear uns aos outros (a menos que sejam SELECT FOR UPDATE)

Você pode ativar o nível de isolamento SNAPSHOT em seu banco de dados e usá-lo, mas nota que isso não impedirá consultas UPDATE que está sendo bloqueado por consultas SELECT (que parece ser o seu caso).

Ele, porém, impedirá consultas SELECT de ser bloqueado por UPDATE.

Observe também que SQL Server, Oracle ao contrário, usos bloquear gerente e mantém encaixar em uma lista na memória associada.

Isso significa que sob carga pesada, o simples fato de colocar e retirar o bloqueio pode ser lenta, uma vez que a lista ligada em si deve ser bloqueado pelo segmento transação.

Para executar sujo lê você pode:

 using (new TransactionScope(TransactionScopeOption.Required, 
 new TransactionOptions { 
 IsolationLevel = System.Transactions.IsolationLevel.ReadUncommitted }))
 {
 //Your code here
 }

ou

SelectCommand = "SELECT * FROM Table1 WITH (NOLOCK) INNER JOIN Table2 WITH (NOLOCK) ..."

lembre-se que você tem que escrever WITH (NOLOCK) depois de cada tabela que deseja leitura suja

Você pode definir o nível de transação a leitura não consolidada

Você também pode obter impasses:

"impasses envolvendo apenas uma tabela" http: // sqlblog.com/blogs/alexander_kuznetsov/archive/2009/01/01/reproducing-deadlocks-involving-only-one-table.aspx

e ou resultados incorretos:

"Seleciona sob READ COMMITTED e REPEATABLE READ pode retornar resultados incorretos."

http://www2.sqlblog.com/blogs/alexander_kuznetsov/archive/2009/04/10/selects-under-read-committed-and-repeatable-read-may-return -incorrect-results.aspx

Você pode usar dica de tabela WITH(READPAST). É diferente do que a WITH(NOLOCK). Ele irá obter os dados antes que a transação foi iniciada e não irá bloquear ninguém. Imagine que, você executou a declaração antes que a transação foi iniciada.

SELECT * FROM table1  WITH (READPAST)
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top