我在SQL服务器中有一个表,它由在不同会话中同时运行的存储过程同时进行CRUD:
|----------------|---------|
| <some columns> | JobGUID |
|----------------|---------|
该程序的工作原理如下:
存储过程中的每个select/insert/update/delete语句都有一个WHERE JobGUID = @jobGUID子句,因此该过程仅适用于它在步骤2中插入的记录.但是,有时当同一存储过程在不同的连接中并行运行时,会发生死锁共享表.以下是SQL Server Profiler的死锁图:

锁定升级不会发生.我尝试向(UPDLOCK, ROWLOCK)所有DML语句添加锁定提示和/或在事务中包装过程的主体并使用不同的隔离级别,但它没有帮助.共享表上的RID锁定仍然相同.
之后我发现共享表没有主键/标识列.一旦我添加它,死锁似乎已经消失:
alter table <SharedTable> add ID int not null identity(1, 1) primary key clustered
Run Code Online (Sandbox Code Playgroud)
当我删除主键列时,死锁又回来了.当我把它添加回来时,我再也无法重现死锁了.
那么,问题是,主键身份列真的能够解决死锁还是巧合?
更新:作为@Catcall建议,我已经尝试创建现有列的自然聚集主键(无添加标识列),但还是抓住了相同的僵局(当然,这一次是一键锁定,而不是RID锁).
我正在处理的应用程序必须处理许多需要更新数据库上的数据的ajax请求.
[Macromedia] [SQLServer JDBC驱动程序] [SQLServer]事务(进程ID 66)在锁定时死锁 与另一个进程通信缓冲资源并被选为死锁牺牲品.重新运行该交易.
对于读取,我已经使用了WITH (NOLOCK)提示,这防止了大量的读取死锁.
我能做些什么来更好地处理写入?
CFLL中的更新代码?
或者有没有办法让SQL Server锁定一行而不是一个表?
有没有人尝试过实施CQRS?似乎解决了这个问题,但我不清楚如何处理:
谢谢