SQLSERVER 2005: Problema de deadlock sem registros compartilhados
-
08-07-2019 - |
Pergunta
Eu tenho um problema de impasse com duas transações que não acessam nenhum registro comum. Também não há escalada de bloqueio. Portanto, não posso explicar por que um impasse é possível.
O impasse ocorre quando duas dessas transações são executadas ao mesmo tempo:
begin transaction
update A set [value] = [value]
where id = 1; /* resp. 2 */
/* synchronize transactions here */
SELECT *
FROM
A inner join B on A.B_FK = B.id
inner join C on C.A_FK = A.id
WHERE
A.[value] = 1; /* resp. 2 */
rollback;
Estas são as tabelas e dados para configurar o cenário:
CREATE TABLE A (
id INT NOT NULL,
[value] INT,
B_FK INT
primary key (id)
)
CREATE TABLE B (
id INT NOT NULL,
primary key (id)
)
CREATE TABLE C (
id INT NOT NULL,
A_FK INT
primary key (id)
)
INSERT INTO A VALUES(1, 1, 1)
INSERT INTO B VALUES(1)
INSERT INTO C VALUES(1, 1)
INSERT INTO A VALUES(2, 2, 2)
INSERT INTO B VALUES(2)
INSERT INTO C VALUES(2, 2)
Mesa A
está no meio de três mesas. Se eu mudar alguma coisa na consulta, por exemplo, remova uma das mesas unidas B
ou C
, não há impasse. O mesmo quando eu filtro A.id
ao invés de A.value
.
O deadlock-Graph me diz que ambos querem definir uma trava para o índice de chave primária da tabela A
. Novamente: não há escalada de bloqueio.
Estou usando o SQLSERVER 2005.
- Por que essas transações estão conflitantes sem acessar dados comuns? Alguém pode explicar isso?
- O que posso fazer para evitar isso? Estou usando o Nibernate e não posso alterar a consulta tão facilmente.
- Poderia ser um problema do SQLServer?
Muito obrigado.
Solução
O conflito pode acontecer, porque o SQL-Server faz o bloqueio não apenas no nível da linha, mas também na página ou no nível da tabela.
Isso significa que um registro pode ser bloqueado, mesmo que não esteja realmente em uso, mas apenas um registro diferente "próximo".
Contenção de bloqueio do servidor SQL domada pode ser útil
Outras dicas
Além disso, outra coisa a considerar quando você às vezes obtém esses problemas é que o bloqueio pode vir do processamento feito por gatilhos.