Muito novato no trabalho do DB, então aprecie sua paciência com uma pergunta básica. Estou executando o SQL Server 2014 em minha máquina local e tenho uma tabela pequena e um aplicativo cliente básico para testar diferentes abordagens. Estou recebendo o que parece ser um bloqueio de tabela durante as instruções INSERT INTO
e UPDATE
. O cliente é um aplicativo ASP.NET com o seguinte código:
OleDbConnection cn = new OleDbConnection("Provider=SQLNCLI11; server=localhost\\SQLEXPRESS; Database=<my db>; user id=<my uid>; password=<my pwd>");
cn.Open();
OleDbTransaction tn = cn.BeginTransaction();
OleDbCommand cmd = new OleDbCommand("INSERT INTO LAYOUTSv2 (LAYOUTS_name_t, LAYOUTS_enabled_b, LAYOUTS_data_m) VALUES ('name', '-1', 'data')", cn, tn);
cmd.ExecuteNonQuery();
cmd.CommandText = "SELECT SCOPE_IDENTITY()";
int newkey = Decimal.ToInt32((decimal)cmd.ExecuteScalar());
Console.WriteLine("Created index " + newkey);
Thread.Sleep(15000);
tn.Commit();
tn = cn.BeginTransaction();
cmd.CommandText = "UDPATE LAYOUTSv2 SET LAYOUTS_enabled_b='-3' WHERE LAYOUTS_key='" + newkey + "'";
cmd.Transaction = tn;
cmd.ExecuteNonQuery();
Console.WriteLine("updated row");
Thread.Sleep(15000);
tn.Rollback();
cn.Close();
Eu corro esse código e, a partir do estúdio de gerenciamento, corro SELECT * FROM LAYOUTSv2
. Nos dois casos em que o encadeamento do cliente é pausado (ou seja, antes da confirmação / reversão), a consulta SELECT trava até que a confirmação / reversão ocorra.
A tabela possui o campo LAYOUTS_key atribuído como a chave primária. Na janela de propriedades, mostra que é exclusivo e agrupado, com bloqueios de página e bloqueios de linha permitidos. A configuração de escalação de bloqueios para a tabela é Desativar ... Tentei as outras configurações disponíveis de Tabela e AUTO sem alterações. Eu tentei SELECT ... WITH (NOLOCK)
e isso retorna um resultado imediatamente, mas como é bem recomendado aqui e em outros lugares, não é o que devo fazer. Eu tentei colocar a ROWLOCK
dica nas declarações INSERT
e UPDATE
, mas nada mudou.
O comportamento que estou procurando é o seguinte: antes da confirmação de um INSERT
, as consultas de outros threads lêem todas as linhas, exceto a que está sendo INSERT
editada. Antes de confirmar uma UPDATE
consulta de outros threads, leia a versão inicial da linha que está sendo UPDATE
editada. Existe alguma maneira de fazer isso? Se precisar fornecer outras informações para esclarecer meu caso de uso, entre em contato. Obrigado.
fonte
WHERE LAYOUTS_key='" + newkey + "'
é um completo não-não por vários motivos, incluindo injeção SQL, você deve usar consultas parametrizadas.newkey
"something';DELETE FROM LAYOUTSv2 --
". Sua atualização seria concluída com êxito e depois esvaziaria a tabela porque o usuário manipulou a consulta inserindo um apóstrofo. Normalmente, uma consulta parametrizada se parece com a seguinteUDPATE LAYOUTSv2 SET LAYOUTS_enabled_b='-3' WHERE LAYOUTS_key=?
, após a qual você atribui valor (es) separadamente ao?
(o parâmetro) no seu código.Respostas:
As chances são de que ele não esteja bloqueando a "tabela inteira".
Ele está bloqueando uma linha na tabela, mas suas
SELECT * FROM LAYOUTSv2
tentativas de ler a tabela inteira são necessariamente bloqueadas por esse bloqueio.Para o caso de inserção, você pode apenas especificar a
READPAST
dica para ignorar a linha bloqueada - no entanto, isso não fornecerá o resultado desejado para oUPDATE
caso (ele ignorará a linha novamente e não lerá a versão inicial da linha).Se você configurar o banco de dados para isolamento de captura instantânea confirmada por leitura, isso proporcionará o efeito desejado para os dois casos (às custas de um maior uso de
tempdb
)fonte
SNAPSHOT
melhor para deixá-lo desativado e ativá-lo se você decidir posteriormente que isso seria útil para você.As instruções de inserção e atualização devem criar bloqueios no nível de linha. No entanto, quando o número de bloqueios em qualquer transação é de 5.000 ou mais, ocorre uma escalação de bloqueios e cria um bloqueio no nível da tabela. Por favor veja abaixo.
https://technet.microsoft.com/en-us/library/ms184286(v=sql.105).aspx
fonte