Ich kann in Ihrem Code keinen expliziten Transaktionsbereich sehen, daher weiß ich nicht, welche Sperren bereits vorhanden sind, wenn Sie Ihr Update durchführen. Es ist auch nicht klar, welche Isolationsstufe Sie verwenden. Das häufigste Szenario in dieser Art von Situation ist jedoch, dass Sie früher in derselben Transaktion eine Auswahl (Lesesperre) für dieselben Zeilen erteilt haben, die Sie später zu aktualisieren versuchen. Dies führt zu einer Eskalation der Sperre und kann zu einem Deadlock führen, wenn zwei Transaktionen dasselbe versuchen:
- Transaktion A:Auswahl mit Lesesperre
- Transaktion B:mit Lesesperre auswählen
- Transaktion A:Update - möchte ihre Lesesperre auf eine Schreibsperre eskalieren, muss aber warten, bis Transaktion B ihre Lesesperre freigibt
- Transaktion B:Update - möchte ihre Lesesperre auf eine Schreibsperre eskalieren, muss aber warten, bis Transaktion A ihre Lesesperre freigibt.
Bingo! Deadlock, da sowohl A als auch B aufeinander warten, um ihre bestehenden Lesesperren freizugeben, bevor sie ihre Aktualisierung durchführen können.
Um dies zu verhindern, benötigen Sie einen Updlock-Hinweis in Ihrer Auswahl, z. B.
select * from table with (updlock) where blah blah
Dadurch wird sichergestellt, dass Ihre Auswahl eine Schreibsperre anstelle einer Lesesperre verwendet, wodurch eine Sperrenausweitung zwischen gleichzeitigen Transaktionen verhindert wird.