SELECT @id = ZipCityId
FROM ZipCity
WHERE MunicipalityID=@MunicipalityId
AND ZipCode=@ZipCode
Here your select is acquiring an S-lock. This can happen with multiple threads. Later, the insert tries to X-lock which is a deadlock.
Acquire the X-lock straight away:
SELECT @id = ZipCityId
FROM ZipCity WITH (XLOCK, ROWLOCK, HOLDLOCK) ...
Here, ROWLOCK, HOLDLOCK
are not strictly required but the pattern XLOCK, ROWLOCK, HOLDLOCK
is pretty standard and I try to follow it everywhere for consistency.
Btw, you might want to switch to a MERGE
statement. I think it will acquire U-locks automatically so no locking hints are required for it. Not sure about that, though. In any case it would be a code improvement as well as a performance improvement.