AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题 / 137728
Accepted
Michael Green
Michael Green
Asked: 2016-05-06 21:41:10 +0800 CST2016-05-06 21:41:10 +0800 CST 2016-05-06 21:41:10 +0800 CST

在回滚期间,锁升级是否被逆转

  • 772

通常,SQL Server 会在更新期间获取锁。它还支持锁升级:

锁升级是将许多细粒度锁转换为较少粗粒度锁的过程,在降低系统开销的同时增加并发竞争的概率。

在事务 ROLLBACK 期间,SQL Server 是否降级锁,放回细粒度锁?

sql-server sql-server-2008-r2
  • 1 1 个回答
  • 1028 Views

1 个回答

  • Voted
  1. Best Answer
    Michael Green
    2016-05-06T21:41:10+08:002016-05-06T21:41:10+08:00

    SQL Server 不会降级锁定。

    我使用包含 100,000 行的“ Numbers ”表进行了调查。根据经验,更新 5,000 行会在sys.dm_tran_locks. 更新另外 10,000 行导致升级到单个表锁。这是始终可重现的。为了尽量减少涉及的对象,该表是一个没有索引的堆。

    我使用扩展事件跟踪来捕获lock_acquired事件lock_released。为了便于分析,我在 UPDATE 和 ROLLBACK 阶段使用了单独的跟踪。

    使用了两个会话(SSMS 窗口)——一个用于 DML 语句,一个用于跟踪 DDL。我无法使用单个会话,因为我想在事务打开时停止和启动跟踪,这是不允许的。整个隔离级别是 READCOMITTED。

    结果select @@VERSION是

    Microsoft SQL Server 2008 R2 (SP2) - 10.50.4042.0 (Intel X86) 2015 年 3 月 26 日 21:49:16 版权所有 (c) Microsoft Corporation Enterprise Edition on Windows NT 6.1(Build 7601:Service Pack 1)

    采取的步骤是

    1. 创建并启动获取跟踪。

      CREATE EVENT SESSION DuringUpdate
      ON SERVER
      ADD EVENT sqlserver.lock_acquired,
      ADD EVENT sqlserver.lock_released
      ADD TARGET package0.asynchronous_file_target
          (SET filename = 'c:\temp\LockRollback\DuringUpdate.xel',
           metadatafile = 'c:\temp\LockRollback\DuringUpdate.xem')
      WITH(EVENT_RETENTION_MODE = NO_EVENT_LOSS,
           MAX_DISPATCH_LATENCY = 1 SECONDS
          );
      
      
      ALTER EVENT SESSION DuringUpdate
      ON SERVER
      STATE = start;
      
    2. 开始一个事务并更新 5000 行。

      begin transaction;
      
      update dbo.Numbers
      set Number = Number
      where Number between 1 and 5000;
      
    3. 再更新 10000 行。

      update dbo.Numbers
      set Number = Number
      where Number between 5001 and 15000;
      
    4. 停止获取跟踪。

      ALTER EVENT SESSION DuringUpdate
      ON SERVER
      STATE = stop;
      
    5. sys.dm_tran_locks通过查询(2 - DB, table)验证是否存在锁。

    6. 创建并启动发布跟踪。

      CREATE EVENT SESSION DuringRollback
      ON SERVER
      ADD EVENT sqlserver.lock_acquired,
      ADD EVENT sqlserver.lock_released
      ADD TARGET package0.asynchronous_file_target
          (SET filename = 'c:\temp\LockRollback\DuringRollback.xel', 
               metadatafile = 'c:\temp\LockRollback\DuringRollback.xem')
      WITH(EVENT_RETENTION_MODE = NO_EVENT_LOSS,
           MAX_DISPATCH_LATENCY = 1 SECONDS
          );
      
      
      ALTER EVENT SESSION DuringRollback
      ON SERVER
      STATE = start;
      
    7. 回滚事务。

      rollback;
      
    8. 停止发布跟踪。

      ALTER EVENT SESSION DuringRollback
      ON SERVER
      STATE = stop;
      
    9. 整理

      DROP EVENT SESSION DuringUpdate
      ON SERVER;
      
      DROP EVENT SESSION DuringRollback
      ON SERVER;
      

    如果发生锁降级,我希望两个跟踪文件完全对称 - 在 UPDATE 和升级期间获取的每个锁在 ROLLBACK 期间都会有相应的释放。我观察到的:

    SELECT 
        COUNT(*) as DuringUpdate
    FROM sys.fn_xe_file_target_read_file(
        'c:\temp\LockRollback\DuringUpdate*.xel', 
        'c:\temp\LockRollback\DuringUpdate*.xem', null, null);
    
    SELECT 
        COUNT(*) as DuringRollback
    FROM sys.fn_xe_file_target_read_file(
        'c:\temp\LockRollback\DuringRollback*.xel', 
        'c:\temp\LockRollback\DuringRollback*.xem', null, null);
    

    分别是 383,889 行和 166 行。检查回滚文件的事件 XML,只有一个与 RID、PAGE 或 OBJECTS 相关的事件——释放表上的 X 锁。我由此得出结论,锁定在回滚期间没有降级。

    这与回滚到命名保存点的文档相呼应:

    指定 savepoint_name 的 ROLLBACK TRANSACTION 语句释放在保存点之后获取的任何锁,升级和转换除外。这些锁没有被释放,也没有转换回它们之前的锁模式。

    • 11

相关问题

  • SQL Server - 使用聚集索引时如何存储数据页

  • 我需要为每种类型的查询使用单独的索引,还是一个多列索引可以工作?

  • 什么时候应该使用唯一约束而不是唯一索引?

  • 死锁的主要原因是什么,可以预防吗?

  • 如何确定是否需要或需要索引

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目

    • 12 个回答
  • Marko Smith

    如何让sqlplus的输出出现在一行中?

    • 3 个回答
  • Marko Smith

    选择具有最大日期或最晚日期的日期

    • 3 个回答
  • Marko Smith

    如何列出 PostgreSQL 中的所有模式?

    • 4 个回答
  • Marko Smith

    列出指定表的所有列

    • 5 个回答
  • Marko Smith

    如何在不修改我自己的 tnsnames.ora 的情况下使用 sqlplus 连接到位于另一台主机上的 Oracle 数据库

    • 4 个回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Martin Hope
    Jin 连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane 如何列出 PostgreSQL 中的所有模式? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh 为什么事务日志不断增长或空间不足? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland 列出指定表的所有列 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney MySQL 能否合理地对数十亿行执行查询? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx 如何监控大型 .sql 文件的导入进度? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve