5
Ho una tabella in SQL Server (SQL Azure):due indici deadlock
CREATE TABLE Commands
(
Id int NOT NULL PRIMARY KEY,
Body nvarchar(1000) NOT NULL,
Priority int NOT NULL,
DeliveryDate datetime NOT NULL,
VisibleFrom datetime NULL,
)
La tabella include anche un indice:
CREATE NONCLUSTERED INDEX IX_PriorityAndDate ON Commands (Priority DESC, DeliveryDate ASC)
Poi ho due sessioni.
Sessione 1
WITH command AS
(
SELECT TOP(1) *
FROM Commands q
WHERE q.DeliveryDate <= @CurrentDate
AND (q.VisibleFrom IS NULL OR q.VisibleFrom <= @CurrentDate)
ORDER BY q.Priority DESC, q.DeliveryDate
)
UPDATE command SET command.VisibleFrom = DATEADD(SECOND, @LeaseTimeout, @CurrentDate)
OUTPUT inserted.Id,
inserted.Body
Sessione 2
DELETE FROM Commands WHERE Id = @Id
In alcuni casi si verifica una situazione di stallo:
- Sessione indice 1 serrature IX_PriorityAndDate (blocco U).
- Sessione 2 blocchi Indice PK_Commands (X lock).
- Sessione 1 blocchi in attesa PK_Commands (acquisizione del blocco U).
- Sessione 2 blocchi in attesa IX_PriorityAndDate (acquisizione X lock).
Come risolvere questo deadlock?
Non è forse un bug logico che lo stesso comando è stato aggiornato ed eliminato allo stesso tempo? Oppure l'accesso all'indice su IX_PriorityAndDate legge più righe? In tal caso, perché c'è un suggerimento UPDLOCK? Rimuovilo e usa READ COMMITTED o l'isolamento dello snapshot. – usr
Non è un bug logico, queste query vengono eseguite in diversi contesti per righe diverse. Lo stesso deadlock si verifica con o senza il suggerimento WITH (UPDLOCK). Lo rimuoverò per rendere più chiara la domanda. – alexey
Con quale livello di isolamento vengono eseguite queste istruzioni? – usr