Sql server sql server中的读写器死锁

Sql server sql server中的读写器死锁,sql-server,Sql Server,是否有任何方法可以避免更新查询死锁而不更改或添加索引 以下查询始终生成死锁 update table1 set Batch_ID=1 where item_id in (select top 300 t1.item_id From table1 t1 inner join table2 t2 on t1.item_id=t2.item_id inner join table3 t3 on t1

是否有任何方法可以避免更新查询死锁而不更改或添加索引

以下查询始终生成死锁

update table1
set Batch_ID=1
where item_id in (select top 300 t1.item_id
                        From    table1 t1 inner join table2 t2 on t1.item_id=t2.item_id
                         inner join table3 t3 on t1.item_ID=t3.item_ID
                        Where   IsNull(t3.item_Delivered,0) = 0
                                And t1.TBatch_ID is Null
                                And t2.Shipper_ID = 2
                                And DateDiff(day,t1.TShipping_Date,getdate()) < 90
                                And (
                                        DateDiff(minute,IsNull(t1.LastTrackingDate,DateAdd(day,-2,GetDate())),getdate()) > 180
                                        OR (DateDiff(minute,IsNull(t1.LastTrackingDate,DateAdd(day,-2,GetDate())),getdate()) > 60 And IsNull(t3.item_Indelivery,0) = 1)
                                )
                                    And t2.Customer_ID not in (700,800)
                        Order By    t1.LastTrackingDate, t2.Customer_ID)
通常我在selectqueryreader上使用set事务隔离级别readuncommitted,但在本例中,它是一个更新查询编写器。因此,我不能应用相同的推理隔离级别

是否有一种方法仅为select子查询设置事务隔离级别

我可以为子查询的select子句中的每个表添加NOLOCK吗


感谢

在满足特定条件的前300行中,查询会将Batch_ID列从NULL切换为1

此更新容易出现死锁,因为如果两个连接同时运行同一个查询,则两个查询都将找到重叠的table1行,并且都将尝试更新。从子查询返回的行与外部更新返回的行之间存在竞争条件

Re:NOLOCK-不,read uncommitted将导致更不可预测的行为。一种选择是通过提高锁定悲观度来同步对更新的并发调用,这样任何并发连接都将被阻止,直到第一批300个连接完成标记,例如:

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
update table1
set Batch_ID=1
where item_id in (select top 300 t1.item_id
                  From    table1 t1 (WITH XLOCK)  ...
SET TRANSACTION ISOLATION READ COMMITTED;

顺便说一句,但请注意,您可以通过直接从表中联接来避免子查询。StuartLC,我如何避免子查询,即,我如何仅通过联接而不使用子查询来仅对前300个项目进行更新?您的帖子在子查询中没有显示前300个项目?我相信这与问题有关。你是对的,我忘了确切地说,应用程序在4台服务器上运行相同的代码,但为了简化,我将set batch_id=1设置为set batch_id=generatedkey,即每次代码运行batch_id有一个新值时,两个批不可能有相同的batch_id值。所以我看不出使用无锁会导致不可预测的行为。