SQL Server 并发控制:Fabric Warehouse只支持快照隔离

前言:最近在项目中用到Fabric Warehouse,于是学习了关于Fabric Warehouse的快照隔离的知识点,整理成本文,希望对读者有所帮助。

Fabric Warehouse只支持快照隔离,这是强制执行的,且不能修改隔离级别,还是默认省略SET ISOLATION SNAPSHOT 语句。

一,Fabric Warehouse 只支持快照隔离级别

不同于传统的数据仓库,Fabric Warehouse对所有事务强制执行快照隔离(Snapshot isolation)。快照隔离是一种基于行的隔离级别,它为数据提供事务级的一致性,并使用存储在 tempdb 中的行版本来选择要更新的行。事务使用事务开始时存在的数据行版本。这确保每个事务都基于事务开始时数据的一致快照进行操作。

在快照隔离中,事务中的查询看到的是相同的版本(或快照),该版本基于事务开始时数据库的状态。在快照隔离中,修改数据的事务不会阻塞读取数据的事务,读取数据的事务也不会阻塞写入数据的事务。这种乐观的非阻塞行为也显著降低了复杂事务发生死锁的可能性。

如果您使用 T-SQL 更改隔离级别,则该更改在查询执行时将被忽略,并应用快照隔离。

SQL Server 和 Fabric Warehouse 快照隔离的基本区别在于:

**区别1:**在 SQL Server 中,只要没有事务同时尝试更新同一行,多个事务就可以修改同一表中的数据;而在 Fabric 中,这是不可能的------即使不是同一行,多个事务也不能修改同一张表中的任何行。

**区别2:**Fabric Warehouse的Snapshot Isolation中的锁模式:

  • Locks are at the table level,任何操作都是在表级别上加锁。
  • Lock types (modes):
    • SELECT: Schema-Stability (Sch-S)
    • INSERT, UPDATE, DELETE, COPY INTO: Intent Exclusive (IX)
    • DDL: Schema-Modification (Sch-M)

二,DDL 阻塞行为

DDL操作会申请Sch-M锁,这个锁会排斥Sch-S和IX锁。因此,对于包含至少一次 DDL 操作的长时间运行事务会降低系统的并发度,阻止其他DML事务的进行。

DDL操作的行为:

  • DDL 操作会在事务存续期间获取目标表的 Sch-M 锁。
  • 这些锁会阻止针对同一表的DML 操作(例如,SELECT、INSERT、UPDATE、DELETE),直到DDL操作完成,释放Sch-M锁。
  • DDL 操作还会获取与 DDL 目标表关联的 sys.tables 和 sys.objects 表中的行的 X 锁,这将阻塞对 sys.tables 和 sys.objects 表执行 SELECT 操作。

由于表上的 Sch-M 锁和 sys.tables 表中行的 X 锁会在事务期间保持,因此如果 DDL 操作是在显式用户事务(即在 BEGIN TRAN 内部)中执行的,则这些锁的持续时间可能会特别长。因此,当查询sys.tables 时,可以使用 sys.tables WITH(READPAST) 表提示(table hint)来缓解元数据查询中的 DDL 阻塞。这使得元数据查询可以跳过当前被排他锁 (X) 锁定的行,这通常是与正在进行 DDL 操作的活动事务中的表相关的行。因此,针对 sys.tables 的查询将不再完全被 DDL 活动阻塞,sys.tables 将返回所有其他可用行,从而在模式更改期间提高系统响应速度和可用性。

**READPAST 表提示(table hint)**的主要功能是跳过锁定行(Skip locked rows),使用语法如下代码所示:

复制代码
SELECT
    [column_name],
    [another_column]
FROM [TableName] WITH (READPAST);

READPAST 表提示(table hint)工作原理:

  • 跳过锁定行(skip locked rows):当另一个事务对一行或多行数据设置了独占锁时,使用 READPAST 的 SELECT 查询会忽略这些特定的行,并检索其余数据。
  • 避免阻塞:查询遇到锁定行时的默认行为是等待锁被释放,READPAST 会修改此行为,允许查询跳过锁定行,只查询非锁定行,并返回结果。
  • 仅读取已提交的数据:与可能返回未提交(或"脏")数据的 NOLOCK 提示不同,READPAST 只会跳过锁定的行,并且仍然只返回已提交的数据。

由于Fabric Warehouse施加的锁是在表级别,当对一个表上执行DDL操作时,这个表只是sys.tables的一行,所以可以对sys.tables应用READPAST 表提示 。

当对一个表执行DML修改操作时,在快照隔离级别下,读操作不会阻塞任何IX操作,也就不需要READPAST 表提示 。

三,DML阻塞行为

Sch-S不会阻塞任何IX锁,也就是:读取数据不会阻塞任何数据修改的操作(Insert,Update和Delete),但是读取到的数据是修改操作开始前的原始数据。不会受到修改操作的影响,即使修改事务的提交时间早于读事务提交的时间。这可能是Fabric Warehouse强制使用快照隔离的原因了,因为读数据操作不会阻塞修改数据操作。

1, 读取数据

在读取数据时使用快照隔离级别,如果我们想要从多个表中读取数据,并确保返回的数据来自同一时间点,那么快照隔离级别就能帮助我们实现这一目标。通过发起事务并读取数据,系统会从表中返回事务发起时的数据。在读取事务期间,表上的数据可以进行修改,但这不会影响最终结果。

微软文档指出:"事务还可以用于顺序执行 SELECT 语句,以确保所有涉及的表都包含来自同一时间点的数据。"

2,修改数据

如果多个事务同时作用于同一张表,那么最先提交的事务会成功,其他事务将会回滚并返回错误。没错,并非是哪个事务先启动......这意味着,如果你有一个耗时较长的 UPDATE 查询,而另一个 UPDATE 查询在它之前启动并提交,那么很遗憾,你耗时较长的 UPDATE 查询将会失败。

微软文档中写道:"两个或多个并发事务更新表中的一行或多行时产生的冲突,会在事务结束时进行评估。第一个提交的事务会成功完成,其他事务将被回滚并返回错误。"

3,插入数据

插入数据时的行为与更新/删除数据时的行为不同。由于多个事务同时插入新数据时,它们会写入新的 Parquet 文件,因此发生冲突的可能性要小得多。对表加锁是为了确保不会对表结构进行任何修改。

微软文档指出:"INSERT 语句总是创建新的 Parquet 文件,这意味着除了 DDL 事务之外,与其他事务的冲突更少,因为 DDL 事务的表结构可能会发生变化。"

4,删除数据

删除操作与更新操作的行为方式相同,先提交的删除事务会胜出,即如果发起一个 DELETE 事务,随后又发起并提交了另一个 DELETE 事务,则原始 DELETE 事务由于未提交将回滚并失败。

报错信息和Update操作相同:

Snapshot isolation transaction aborted due to update conflict. Using snapshot isolation to access table 'DimProducts' directly or indirectly in database 'SalesDataWarehouse' can cause update conflicts if rows in that table have been deleted or updated by another concurrent transaction. Retry the transaction.

5,了解 Fabric Warehouse中的写写冲突

当两个事务尝试对同一张表执行 UPDATE、DELETE、MERGE 或 TRUNCATE 操作时,可能会发生写写冲突。

由于 Fabric 数据仓库使用表级锁定,因此表级也可能出现写写冲突或更新冲突。即使两个事务尝试修改同一张表中的不同行,它们仍然可能发生冲突。

写写冲突主要是由多个用户或进程同时修改同一张表引起的,如果发生写写冲突,您可能会看到如下错误消息:

  • Error 24556: Snapshot isolation transaction aborted due to update conflict. Using snapshot isolation to access table '%.*ls' directly or indirectly in database '%.*ls' can cause update conflicts if rows in that table have been deleted or updated by another concurrent transaction. Retry the transaction.
  • Error 24706: Snapshot isolation transaction aborted due to update conflict. You cannot use snapshot isolation to access table '%.*ls' directly or indirectly in database '%.*ls' to update, delete, or insert the row that has been modified or deleted by another transaction. Please retry the transaction.

如果您遇到这些错误消息,则表示一个或多个事务已成功执行,但一个或多个冲突事务失败。请重试失败的事务。

四,查看Fabric Warehouse的锁

使用sys.dm_tran_locks来查看锁和排除冲突的故障。

复制代码
SELECT
    DB_NAME(resource_database_id) AS DatabaseName,
    OBJECT_NAME(resource_associated_entity_id) AS ObjectName,
    resource_type,
    CASE request_mode
        WHEN 'IX' THEN 'Intent Exclusive'
        WHEN 'Sch-S' THEN 'Schema Stability'
        WHEN 'Sch-M' THEN 'Schema Modification'
        WHEN 'S' THEN 'Shared'
        WHEN 'U' THEN 'Update'
        WHEN 'X' THEN 'Exclusive' 
        WHEN 'IS' THEN 'Intent Shared' 
        WHEN 'IU' THEN 'Intent Update' 
        WHEN 'IX' THEN 'Intent Exclusive'
        WHEN 'SIU' THEN 'Shared Intent Update' 
        WHEN 'SIX' THEN 'Shared Intent Exclusive' 
        WHEN 'UIX' THEN 'Update Intent Exclusive'
        ELSE request_mode
    END AS LockRequestModeDesc,
    request_mode,
    request_type,
    request_status,
    request_reference_count,
    request_session_id,
    resource_associated_entity_id
FROM sys.dm_tran_locks

五,查看tempdb的使用

在 Microsoft Fabric 中,数据仓库对所有事务都使用快照隔离。当数据被修改时,Fabric 引擎会在 tempdb 中创建并存储行版本,以确保读取的一致性。由于 tempdb 是一个受管系统数据库,您无法直接访问它,但可以通过 Fabric 内置的监控工具来监控和管理 tempdb 的使用情况。

Snapshot Isolation影响tempdb的四种方式:

  • Row versioning: When a SNAPSHOT isolation transaction begins, it receives a transaction sequence number. When that transaction needs to read data, it retrieves the row version from tempdb that was current at the time the transaction started.
  • Copy-on-write: Whenever a row is modified (updated or deleted), a copy of the original committed row is moved to the version store in tempdb before the change is applied to the main table. This allows other transactions to continue reading the original data without being blocked.
  • Write-write conflicts: In Fabric, snapshot isolation operates at the table level for updates and deletes, not just the row level as in traditional SQL Server. This means concurrent modification operations on the same table will cause a write-write conflict and one transaction will be aborted.
  • Long-running transactions: If a transaction is long-running, it can retain a large number of row versions in tempdb, potentially causing excessive disk usage.

由于 tempdb 由 Fabric 管理,因此您无法像在传统 SQL Server 中那样运行类似 `sys.dm_db_file_space_usage` 的 T-SQL 查询。您必须使用以下工具:

  • Fabric Capacity Metrics App
  • Performance Dashboard

参考文档:

Transactions and Isolation Levels in Fabric Warehouse

Transactions in Fabric Data Warehouse

相关推荐
谅望者2 小时前
SQL子查询完全指南:从零掌握嵌套查询的三种用法与最佳实践
数据库·sql·数据库开发·子查询
翔云 OCR API2 小时前
承兑汇票识别接口原理-OCR赋能票据自动化处理
运维·自动化·ocr
考虑考虑2 小时前
Ubuntu服务器使用 Graphics2D 生成图片时出现文字乱码
运维·服务器·后端
阿萨德528号3 小时前
Redis 分布式锁进阶:跨语言场景下的锁兼容性与一致性保障
数据库·redis·分布式
开开心心就好3 小时前
电脑音质提升:杜比全景声安装详细教程
java·开发语言·前端·数据库·电脑·ruby·1024程序员节
让学习成为一种生活方式3 小时前
调控大肠杆菌胞内ATP和NADH水平促进琥珀酸生产--文献精读172
数据库
yoi啃码磕了牙3 小时前
Unity—Localization 多语言
java·数据库·mysql
DolphinScheduler社区3 小时前
Apache DolphinScheduler 3.3.2 正式发布!性能与稳定性有重要更新
大数据·开源·apache·任务调度·海豚调度·发版
SeaTunnel3 小时前
Apache SeaTunnel 支持 Metalake 开发了!避免任务配置敏感信息暴露
大数据·开源·apache·个人开发·数据集成·seatunnel·看开源之夏