Muito novato no trabalho de banco de dados, então agradeço sua paciência com uma pergunta básica. Estou executando o SQL Server 2014 em minha máquina local e tenho uma pequena tabela 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 este código, então do estúdio de gerenciamento eu corro SELECT * FROM LAYOUTSv2
. Durante ambos os casos, quando a thread do cliente é pausada (ou seja, antes do commit/rollback), a consulta SELECT trava até que ocorra o commit/rollback.
A tabela tem o campo LAYOUTS_key atribuído como chave primária. Na janela de propriedades, mostra que é único e agrupado, com bloqueios de página e bloqueios de linha permitidos. A configuração de escalonamento de bloqueio 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 avisado aqui e em outros lugares, não é o que eu deveria estar fazendo. Eu tentei colocar a ROWLOCK
dica nas declarações INSERT
e UPDATE
, mas nada mudou.
O comportamento que estou procurando é este: antes do commit de um INSERT
, as consultas de outros threads leem todas as linhas, exceto a que está sendo INSERT
ed. Antes de confirmar uma UPDATE
consulta de outros encadeamentos, leia a versão inicial da linha que está sendo UPDATE
editada. Existe alguma maneira de eu fazer isso? Se eu precisar fornecer outras informações para esclarecer meu caso de uso, por favor me avise. Obrigado.