SQL Server删除锁定问题

时间:2014-04-23 14:16:26

标签: sql-server locking delete-row isolation

我有一个SQL Server数据库,我通过SQL作业中安排的SQL脚本批量删除三个表A,B,C中的行。由于表格包含大量数据,因此作业运行2小时。当作业正在运行时,我的前端应用程序无法访问(给出超时错误),因为应用程序在这些相同的表A,B,C中插入和更新数据。

在SQL脚本运行时,前端应用程序是否可以并行运行而没有任何问题?我检查了表上的锁,SQL Server正在获取页锁。可以Read Committed SnapshotSnapshot隔离级别或将页锁转换为行锁有助于此。需要建议。

2 个答案:

答案 0 :(得分:2)

分两个阶段分割操作。在第一阶段,收集要删除的行的主键:

create table #TempList (ID int);

insert  #TempList
select  ID
from    YourTable

在第二阶段,使用循环以小批量删除这些行:

while 1=1
    begin
    delete  top (1000)
    from    YourTable
    where   ID in (select ID from #TempList)

    if @@rowcount = 0
        break
    end

较小的批次将允许您的前端应用程序在它们之间继续。

答案 1 :(得分:0)

我怀疑SQL Server在某些时候升级为表锁,这意味着该表无法访问,无论是用于读取还是更新。

要在处理大型删除时优化锁定和并发,请使用批处理。此时从5000行开始(以防止锁定升级)并监视其行为方式以及是否需要进一步调整或调低。 5000是一个神奇的数字",但它的数字足够低,锁定管理员不会考虑升级到表锁定,并且足够大以保证性能。

是否会发生超时取决于其他因素,但如果不完全消除,这肯定会减少。如果读取操作发生超时,您应该能够摆脱它们。当然,另一种方法是增加客户端的命令超时值。

快照(乐观)隔离也是一个选项,READ COMMITTED SNAPSHOT更精确,但它不会帮助其他会话的更新。另外,要注意版本存储(在tempdb中)的增长。如果将其与建议的批处理方法结合使用以保持较小的事务,则最好。

此外,如果数据库正常完全恢复,请在删除期间切换到批量日志恢复。但是一旦完成就切换回来,并进行备份。

几乎忘了 - 如果是SQL Server的企业版,请对您的表进行分区;然后你就可以把分区切换出来,它几乎是偶然的,客户永远不会注意到它。