I have a table in SQL server that is CRUD-ed concurrently by a stored procedure running simultaneously in different sessions:

`|----------------|---------|`  

`| <some columns> | JobGUID |`  

`|----------------|---------|`  

The procedure works as follows:

1. Generate a GUID.
2. Insert some records into the shared table described above, marking them with the GUID from step 1.
3. Perform a few updates on all records from step 2.
4. Select the records from step 3 as SP output.

Every select / insert / update / delete statement in the stored procedure has a `WHERE JobGUID = @jobGUID` clause, so the procedure works only with the records it has inserted on step 2. However, sometimes when the same stored procedure runs in parallel in different connections, deadlocks occur on the shared table. Here is the deadlock graph from SQL Server Profiler:

![SQL Server Profiler Deadlock Graph](https://i.stack.imgur.com/wA5Od.png)

Lock escalations do not occur. I tried adding `(UPDLOCK, ROWLOCK)` locking hints to all DML statements and/or wrapping the body of the procedure in a transaction and using different isolation levels, but it did not help. Still the same RID lock on the shared table.

After that I've discovered that the shared table did not have a primary key/identity column. And once I added it, deadlocks seem to have disappeared:

```
alter table <SharedTable> add ID int not null identity(1, 1) primary key clustered

```

When I remove the primary key column, the deadlocks are back. When I add it back, I cannot reproduce the deadlock anymore.

So, the question is, is a primary key identity column really able to resolve deadlocks or is it just a coincidence?

**Update:** as [@Catcall](https://stackoverflow.com/users/562459/catcall "Catcall") suggests, I've tried creating a natural clustered primary key on the existing columns (without adding an identity column), but still caught the same deadlock (of course, this time it was a key lock instead of RID lock).