代码之家  ›  专栏  ›  技术社区  ›  ColinMac

是否可以从活动(大量数据移动)存储过程中释放事务日志锁?

  •  0
  • ColinMac  · 技术社区  · 5 年前

    编辑的准确术语:

    我们的数据集市中每天都有大量的数据流。其中一些最大的存储过程由ssis管理,需要几个小时。这些长时间运行的存储过程阻止了事务日志的清除(这使问题复杂化,因为我们有许多SP同时运行,然后所有这些SP都会在不截断的情况下写入T-Log)。最终这会破坏我们的数据库,我们被迫从早上的快照中恢复。

    我们已经研究了在SP中执行“sub”提交,但据我所知,您不能完全释放活动存储过程中的事务日志,因为它本身就是一个事务。

    如果不将我们的大型SP重构为成批运行,或者这样做,是否可以在活动SP中定期提交事务日志,以便释放事务日志上的锁?

    编辑/扩展:

    也许我错在上面: 在sp中间歇性提交会允许事务日志截断吗?

    1 回复  |  直到 5 年前
        1
  •  3
  •   David Browne - Microsoft    5 年前

    在sp中间歇性提交会允许事务日志截断吗?

    如果客户机启动一个事务,它不是 推荐 在存储过程中提交该事务。它不是 允许 以不同于输入时使用的@@TranCount退出存储过程。

    以下模式是 技术上 允许,尽管我从未见过它在现实世界中使用:

    use tempdb
    if @@trancount > 0 rollback
    go
    drop table if exists T
    create table T(id int identity)
    go
    create or alter procedure tranTest
    as
    begin
    
      insert into T default values
    
      commit transaction
    
      begin transaction
    
    end
    go
    
    begin transaction 
    exec tranTest
    select * from T
    rollback
    
    go 5
    

    对于客户机代码来说,回滚事务而不回滚存储过程的工作是非常令人困惑的。

    如果客户机不启动事务,则可以在存储过程中有多个事务,但事务的最小粒度是单个DML语句。因此,每个插入、更新、删除或合并都将在单个事务中运行。

    解决这一问题的实际方法是,按善的降序排列:

    1)增加日志文件的可用存储空间以适应事务。

    2)重构ETL以使用较短的事务,可能在声明表中准备好数据,并在单个最终事务中加载或切换数据。

    3)将ETL重构成小批量运行。