Sql server SQL Server,插入一行锁定整个表
我们有一个僵局的问题,我发布了这个 在一些帮助和大量的自我搜索下,我相信我找到了发生的事情。为了在不控制锁升级的情况下解决死锁,我需要理解为什么sql server会在插入一行时锁定整个表 这是我的insert语句(带有重命名的变量): 我不知道这样做是因为还是因为它从一开始就请求表上的独占锁。无论如何,这给我带来了死锁的麻烦 单个表上有16个锁行的原因是 我的问题是,为什么它不请求表上的意图独占锁(IX)?相反,它请求独占锁。我如何防止这种情况?我在tuning advisor中没有得到任何调优提示,我已经尝试过了 编辑 我们的表格上有一个insert触发器,它更新了我们表格3上的一个字段。看起来是这样的:Sql server SQL Server,插入一行锁定整个表,sql-server,tsql,insert,locking,Sql Server,Tsql,Insert,Locking,我们有一个僵局的问题,我发布了这个 在一些帮助和大量的自我搜索下,我相信我找到了发生的事情。为了在不控制锁升级的情况下解决死锁,我需要理解为什么sql server会在插入一行时锁定整个表 这是我的insert语句(带有重命名的变量): 我不知道这样做是因为还是因为它从一开始就请求表上的独占锁。无论如何,这给我带来了死锁的麻烦 单个表上有16个锁行的原因是 我的问题是,为什么它不请求表上的意图独占锁(IX)?相反,它请求独占锁。我如何防止这种情况?我在tuning advisor中没有得到任何调
UPDATE OurTable3 SET Date1 = NULL
FROM OurTable3 as E
JOIN OurTable2 as C on E.Id = C.FKId
JOIN OurTable as ETC on ETC.FKId = C.Id
AND (ETC.Date2 IS NULL OR CAST(ETC.Date2 AS DATE) > E.Date1)
AND ETC.Type1 = 1
如您所见,它不更新我们的表,而是查询我们的表,以便更新表3中的正确行。我找到了答案。我们团队中的一个开发人员犯了一个小错误(我总是责怪其他人:-)。 我可能已经知道答案了,因为Martin Smith在另一个问题中再次指出,我应该检查ALLOW_ROW_LOCKS和ALLOW_PAGE_LOCKS。但当时我们认为分区id与索引id相关,我只检查了该索引 我所做的是用相同的数据创建一个新表。效果消失了,我在新表上只有正确的IX锁。然后,我创建了每个索引,并在每个创建之间进行测试,直到我突然再次产生效果 我在我们的表上找到了这个索引:
CREATE NONCLUSTERED INDEX [IX_OurTable] ON [dbo].[OurTable]
(
[Col1] ASC,
[Col2] ASC,
[Col3] ASC,
[Col4] ASC,
[Col5] ASC
)
INCLUDE ( [Col6],
[Col7],
[Col8],
[Col9]) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = OFF, ALLOW_PAGE_LOCKS = OFF, FILLFACTOR = 90) ON [PRIMARY]
GO
使用ALLOW_ROW_LOCKS=OFF和ALLOW_PAGE_LOCKS=OFF,很明显我们会对插入和选择产生这种影响
感谢您的评论,也非常感谢Martin,他真的帮助我解决了这些死锁问题。您看过事务隔离级别了吗?所有这些函数是否也可以引用我们的表?你在那里运行了很多函数…表的结构是什么??你有集群密钥吗?如果你只是插入不引用函数的常量,你会看到相同的锁定行为吗?你在这个表上有插入触发器吗?谢谢分享你的解决方案,这看起来很棘手,我相信你的帖子会帮助其他人。
resource_type resource_associated_entity_id Name resource_lock_partition request_mode request_type request_status
OBJECT 290100074 OurTable 0 X LOCK GRANT
OBJECT 290100074 OurTable 1 X LOCK GRANT
OBJECT 290100074 OurTable 2 X LOCK GRANT
OBJECT 290100074 OurTable 3 X LOCK GRANT
OBJECT 290100074 OurTable 4 X LOCK GRANT
OBJECT 290100074 OurTable 5 X LOCK GRANT
OBJECT 290100074 OurTable 6 X LOCK GRANT
OBJECT 290100074 OurTable 7 X LOCK GRANT
OBJECT 290100074 OurTable 8 X LOCK GRANT
OBJECT 290100074 OurTable 9 X LOCK GRANT
OBJECT 290100074 OurTable 10 X LOCK GRANT
OBJECT 290100074 OurTable 11 X LOCK GRANT
OBJECT 290100074 OurTable 12 X LOCK GRANT
OBJECT 290100074 OurTable 13 X LOCK GRANT
OBJECT 290100074 OurTable 14 X LOCK GRANT
OBJECT 290100074 OurTable 15 X LOCK GRANT
UPDATE OurTable3 SET Date1 = NULL
FROM OurTable3 as E
JOIN OurTable2 as C on E.Id = C.FKId
JOIN OurTable as ETC on ETC.FKId = C.Id
AND (ETC.Date2 IS NULL OR CAST(ETC.Date2 AS DATE) > E.Date1)
AND ETC.Type1 = 1
CREATE NONCLUSTERED INDEX [IX_OurTable] ON [dbo].[OurTable]
(
[Col1] ASC,
[Col2] ASC,
[Col3] ASC,
[Col4] ASC,
[Col5] ASC
)
INCLUDE ( [Col6],
[Col7],
[Col8],
[Col9]) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = OFF, ALLOW_PAGE_LOCKS = OFF, FILLFACTOR = 90) ON [PRIMARY]
GO