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.
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 seguinte UDPATE 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.
WHERE LAYOUTS_key='" + newkey + "'
é um completo não-não por vários motivos, incluindo injeção SQL, você deve usar consultas parametrizadas.