AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / dba / Perguntas / 11571
Accepted
King Chan
King Chan
Asked: 2012-01-26 08:20:03 +0800 CST2012-01-26 08:20:03 +0800 CST 2012-01-26 08:20:03 +0800 CST

Alguém pode explicar por que selecionar com nolock consultará uma poção de dados atualizados?

  • 772

Eu estava lendo a resposta daqui (de stackoverflow, acho que deveria perguntar aqui)

NOLOCK significa não colocar nenhum cadeado.

Sua consulta pode retornar partes de dados antes de UPDATE e partes posteriores a UPDATE em uma única consulta.

Entendo que o nolock não colocará o bloqueio na tabela, para que outras pessoas possam consultar ao mesmo tempo.

A partir da resposta e do exemplo mostrado, ele busca dados enquanto os dados estão sendo atualizados.

Por que isso acontece?

Estou assumindo que, para a seleção normal, ele tentará colocar o bloqueio na tabela; portanto, quando a instrução de atualização for executada, ele colocará um bloqueio na linha ou na página. Então, quando tento executar a instrução select, ela não pode colocar o bloqueio até que o bloqueio da instrução de atualização seja liberado.

Mas neste caso porque a instrução select não tenta colocar lock na tabela, então ela pode rodar sem esperar que a instrução update libere o lock?

sql-server select
  • 2 2 respostas
  • 7041 Views

2 respostas

  • Voted
  1. Best Answer
    Martin Smith
    2012-01-26T09:34:45+08:002012-01-26T09:34:45+08:00

    Não é bem verdade que isso NOLOCKsignifica não colocar fechaduras. As consultas sob esta dica ainda terão Sch-Sbloqueios e ( possivelmente HOBT bloqueios).

    No read committednível de isolamento, o SQL Server ( normalmente ) obterá bloqueios de nível de linha Se os liberará assim que os dados forem lidos. Eles são incompatíveis com os Xbloqueios mantidos em atualizações não confirmadas e, portanto, evitam leituras sujas.

    No exemplo da resposta vinculada, a SELECTconsulta não é bloqueada quando encontra uma linha modificada, portanto, é bastante provável que a leitura de atualizações parciais.

    Também pode acontecer no read committednível de isolamento padrão, embora um SELECTleia algumas linhas com o valor "antes" e outras com o valor "depois". Só é necessário criar uma situação em que

    1. A consulta selecionada lê o valor da linha R1e libera seu Sbloqueio
    2. Atualizar consulta atualiza R2e leva um Xbloqueio
    3. A consulta selecionada tenta ler R2e é bloqueada.
    4. Atualizar consulta atualiza R1e leva um Xbloqueio.
    5. A transação de atualização confirma, liberando assim seus bloqueios e permitindo que o Select leiaR2

    Esse tipo de situação pode surgir, por exemplo, se o SELECTe UPDATEestiver usando índices diferentes para localizar as linhas de interesse.

    Exemplo

    CREATE TABLE T
    (
    X INT IDENTITY PRIMARY KEY,
    Y AS -X UNIQUE,
    Name varchar(10),
    Filler char(4000) DEFAULT 'X'
    )
    
    
    INSERT INTO T (Name)
    SELECT TOP 2500 'A'
    FROM master..spt_values
    

    Agora, em uma janela de consulta, execute

    DECLARE @Sum int
    
    SELECT 'SET @@ROWCOUNT' WHERE 1=0
    
    WHILE (@@ROWCOUNT = 0)
    SELECT @Sum = SUM(LEN(Name))
    FROM T 
    WHERE Y IN (-1, -2500)
    HAVING SUM(LEN(Name)) = 3
    

    Isso será executado em um loop infinito. Em outra corrida

    UPDATE T 
    SET Name=CASE WHEN Name = 'A' THEN 'AA' ELSE 'A' END
    

    Isso provavelmente interromperá o loop na outra consulta (tente novamente, caso contrário), o que significa que deve ter lido A,AAouAA,A

    • 11
  2. Fabricio Araujo
    2012-01-26T10:10:29+08:002012-01-26T10:10:29+08:00

    A dica NOLOCKequivale ao nível de isolamento da transação READ UNCOMMITTED, apenas restrita ao escopo de um método de acesso à tabela.

    Qual RU faz com que o não confirmado apareça no seu conjunto de resultados? Hmm, na verdade é uma questão de " o que não faz . Vou explicar abaixo.

    Bem (isso é uma simplificação grosseira, eu sei) MSSQL (em seu comportamento padrão) é um mecanismo de bloqueio - o que significa que ele usa bloqueio para ler/gravar dados de maneira consistente. Nesta explicação simplificada, o MSSQL usa dois tipos de bloqueios: bloqueio compartilhado e bloqueio exclusivo .

    Um bloqueio compartilhado (S) é um bloqueio que permite que um recurso (que pode ser uma linha, página de linhas ou até mesmo uma tabela inteira) seja lido - mas não permite uma gravação nele. Portanto, se a transação T1 colocar um bloqueio S na linha R1, todas as transações que tentarem ler R1 obterão essa leitura, mas enquanto o bloqueio S estiver ativo, ninguém poderá gravar em R1.

    Um bloqueio exclusivo(X) é a contrapartida do bloqueio compartilhado. Ele permite acesso exclusivo a um recurso - nenhuma outra transação pode ler ou escrever, exceto aquela que obteve o bloqueio X. No exemplo acima, se T1 obteve não um bloqueio S, mas um bloqueio X em R1, ninguém, exceto T1, pode lê-lo ou escrevê-lo.

    Essa é a teoria. Os níveis de isolamento respeitam as fechaduras, respeitando a sua prevalência e características. Todos, exceto READ UNCOMMITTED. É simples dar um * (coloque aqui seu palavrão de sua preferência) para os bloqueios referentes à leitura - você ainda não pode atualizar a linha outra transação obteve um bloqueio X. Ele simplesmente diz: "Vou ler tudo o que é relevante para o plano de consulta - desconsidere quais bloqueios estão nele." E faça isso.

    • 3

relate perguntas

  • SQL Server - Como as páginas de dados são armazenadas ao usar um índice clusterizado

  • Preciso de índices separados para cada tipo de consulta ou um índice de várias colunas funcionará?

  • Quando devo usar uma restrição exclusiva em vez de um índice exclusivo?

  • Quais são as principais causas de deadlocks e podem ser evitadas?

  • Como determinar se um Índice é necessário ou necessário

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Como ver a lista de bancos de dados no Oracle?

    • 8 respostas
  • Marko Smith

    Quão grande deve ser o mysql innodb_buffer_pool_size?

    • 4 respostas
  • Marko Smith

    Listar todas as colunas de uma tabela especificada

    • 5 respostas
  • Marko Smith

    restaurar a tabela do arquivo .frm e .ibd?

    • 10 respostas
  • Marko Smith

    Como usar o sqlplus para se conectar a um banco de dados Oracle localizado em outro host sem modificar meu próprio tnsnames.ora

    • 4 respostas
  • Marko Smith

    Como você mysqldump tabela (s) específica (s)?

    • 4 respostas
  • Marko Smith

    Como selecionar a primeira linha de cada grupo?

    • 6 respostas
  • Marko Smith

    Listar os privilégios do banco de dados usando o psql

    • 10 respostas
  • Marko Smith

    Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Como faço para listar todos os bancos de dados e tabelas usando o psql?

    • 7 respostas
  • Martin Hope
    Mike Walsh Por que o log de transações continua crescendo ou fica sem espaço? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland Listar todas as colunas de uma tabela especificada 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney O MySQL pode realizar consultas razoavelmente em bilhões de linhas? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx Como posso monitorar o andamento de uma importação de um arquivo .sql grande? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison Como você mysqldump tabela (s) específica (s)? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    pedrosanta Listar os privilégios do banco de dados usando o psql 2011-08-04 11:01:21 +0800 CST
  • Martin Hope
    Jonas Como posso cronometrar consultas SQL usando psql? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas Como faço para listar todos os bancos de dados e tabelas usando o psql? 2011-02-18 00:45:49 +0800 CST
  • Martin Hope
    bernd_k Quando devo usar uma restrição exclusiva em vez de um índice exclusivo? 2011-01-05 02:32:27 +0800 CST

Hot tag

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve