首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何防止LCK_M_IX等待/锁定以下删除和插入查询

如何防止LCK_M_IX等待/锁定以下删除和插入查询
EN

Database Administration用户
提问于 2019-09-25 04:14:46
回答 2查看 5.5K关注 0票数 2

*编辑:在这里的答案中,解决方案没有什么意义,我在Python中使用了SQLAlchemy,这是一个ORM。我在事务中执行下面的delete语句,但从未提交。这导致大约10个打开的事务发生,最终需要回滚所有事务,从而锁定整个表,直到回滚完成。

给定下表结构,记录将以最近日期时间的update_time连续插入。到DB的一个单独连接是定期修剪旧记录,其日期大于2周。

表结构:

以下Insert正在以不同的值频繁运行:

重复以下delete语句,直到需要为止,然后运行select,以查看进程是否完成

代码语言:javascript
运行
复制
delete top(5000) from trade_options with (READPAST) where update_time < '<Two Weeks Ago>'

Activity显示删除正在锁定,插入正在等待( LCK_M_IX):

谢谢

**编辑:以下是作为脚本输出的索引/键

代码语言:javascript
运行
复制
CREATE NONCLUSTERED INDEX [IX_order_option] ON [dbo].[order_option]
(
    [update_time] DESC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO

ALTER TABLE [dbo].[order_option] ADD PRIMARY KEY CLUSTERED 
(
    [exchange_id] ASC,
    [symbol] ASC,
    [update_time] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
EN

回答 2

Database Administration用户

发布于 2019-09-25 07:27:44

我认为上述情况是非常正常的情况,当您想要删除和插入记录的同时,不确定插入是否只发生在工作时间,甚至在工作时间之后。我建议将这些delete语句放在SQL作业中,并在数据库上活动非常少/没有活动的情况下,每天深夜对它们进行调度。这将防止对数据库的任何阻塞。

正如Darko在上一个答复中提到的,在执行删除时考虑较小的数据块,并在完成时继续提交数据。如果您可以在此表的顶部创建一个视图,并使用您的条件从该视图中删除,这将更加容易,正如Brent Ozar 这里先生所解释的那样。

如果您的操作运行在24*7,则可以用Daniel 这里先生的示例很好地解释。

上面的希望是有帮助的。

票数 2
EN

Database Administration用户

发布于 2019-09-25 06:30:57

删除行时应使用较小的块。但这解决不了你的问题。如果在事务中执行DELETE语句,则行锁可能升级到表锁。

我不知道能否在插入过程中应用表锁?它的意思是使用“WITH(XLOCK)”选项。这是您的应用程序允许的吗?

更重要的是,检查索引并不是个坏主意。你有“update_time”专栏的吗?

这个故事的寓意是,锁定是正常的Server行为,您无法避免这种行为。你唯一能做的就是缩短等待时间。

internet 生成自定义阻塞进程报告上有一个资源可以帮助您轻松检测锁定。

票数 1
EN
页面原文内容由Database Administration提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://dba.stackexchange.com/questions/249550

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档