Ik zie geen expliciete transactieomvang in uw code, dus ik weet niet welke vergrendelingen er al zijn wanneer u uw update uitvoert; ook is het niet duidelijk welk isolatieniveau u gebruikt. Maar het meest voorkomende scenario in dit soort situaties is dat u eerder in dezelfde transactie een select (lees slot) hebt uitgegeven op dezelfde rijen die u later probeert bij te werken. Dit veroorzaakt een escalatie van de vergrendeling en kan leiden tot een impasse als twee transacties hetzelfde proberen te doen:
- Transactie A:selecteren met leesvergrendeling
- Transactie B:selecteren met leesvergrendeling
- Transactie A:update - wil de leesvergrendeling escaleren naar een schrijfvergrendeling, maar moet wachten tot transactie B de leesvergrendeling vrijgeeft
- Transactie B:update - wil de leesvergrendeling escaleren naar een schrijfvergrendeling, maar moet wachten tot transactie A de leesvergrendeling vrijgeeft.
Bingo! impasse omdat zowel A als B op elkaar wachten om hun bestaande leesvergrendelingen vrij te geven voordat ze hun update kunnen uitvoeren.
Om dit te voorkomen, heb je een updlock-hint nodig in je selectie, bijvoorbeeld
select * from table with (updlock) where blah blah
Dit zorgt ervoor dat uw selectie een schrijfvergrendeling gebruikt in plaats van een leesvergrendeling, waardoor escalatie van de vergrendeling tussen gelijktijdige transacties wordt voorkomen.