Domanda

Ho un problema di deadlock con due transazioni che non accedono ad alcun record comune. Non esiste inoltre alcuna escalation di blocco. Quindi non posso spiegare perché sia ??possibile un deadlock.

Il deadlock si verifica quando due di queste transazioni vengono eseguite contemporaneamente:

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;

Queste sono le tabelle e i dati per impostare lo scenario:

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) 

Tabella A è al centro di tre tabelle. Se cambio qualcosa nella query, ad esempio rimuovo una delle tabelle unite B o C , non c'è deadlock. Lo stesso quando filtro per A.id anziché A.value .

Il deadlock-graph mi dice che entrambi vogliono impostare un blocco S sull'indice della chiave primaria della tabella A . Ancora una volta: non c'è escalation di blocco.

Sto usando SqlServer 2005.

  • Perché queste transazioni sono in conflitto senza accedere a dati comuni? Qualcuno può spiegare questo?
  • Cosa posso fare per evitarlo? Sto usando NHibernate e non posso cambiare la query così facilmente.
  • Potrebbe essere un problema SqlServer?

Grazie mille.

È stato utile?

Soluzione

Il conflitto potrebbe verificarsi perché SQL Server non blocca solo a livello di riga, ma anche a livello di pagina o persino di tabella.

Ciò significa che un record può essere bloccato anche se in realtà non è in uso, ma solo un record diverso "vicino".

Contesa di blocco di SQL Server domata potrebbe essere utile

Altri suggerimenti

Inoltre, un'altra cosa da considerare quando si verificano a volte questi problemi è che il blocco potrebbe provenire dall'elaborazione eseguita dai trigger.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top