适用于:✅SQL 分析终结点和 Microsoft Fabric 中的仓库
与 SQL Server 中的行为类似,事务允许你控制读取和写入查询的提交或回滚。
Fabric 数据仓库支持符合 ACID 的事务。 每个事务都是原子的、一致的、隔离的和持久的(ACID)。 单个事务中的所有操作都以原子性的方式处理,要么全部成功,要么全部失败。 如果事务中的任何语句失败,则会回滚整个事务。
显式事务
可以使用显式事务将更改组合在一起,修改存储在仓库中的表中的数据。
例如,可以向多个表提交插入,或者如果出现错误,则不向任何表提交插入。 如果要更改影响三个表的采购订单的详细信息,则可以将这些更改分组到单个事务中。 这意味着当查询这些表时,它们要么全部有更改,要么没有任何更改。 当需要确保多个表中的数据一致时,事务是一种常见做法。
可以将标准 T-SQL(BEGIN TRAN和COMMIT TRANROLLBACK TRAN)语法控制机制用于显式事务。 有关详细信息,请参阅: - BEGIN TRANSACTION
- COMMIT TRANSACTION
- ROLLBACK TRANSACTION
跨数据库查询事务支持
在 Microsoft Fabric 中,仓库支持在同一工作区内跨多个仓库进行事务处理,包括从 Lakehouse 的 SQL 分析终结点进行读取。 有关示例,请参阅 编写跨数据库 SQL 查询。
了解 Fabric 数据仓库中的锁定和阻止
Fabric 数据仓库使用表级锁定,无论查询是涉及一行还是多行。 下表提供了不同 T-SQL 操作所使用的锁列表。
| 语句类型 | 已锁定 |
|---|---|
| DML | |
| SELECT | Schema-Stability (Sch-S) |
| INSERT | 意向独占 (IX) |
| DELETE | 意向独享 (IX) |
| UPDATE | 意向独占 (IX) |
| 合并 | 意向独占 (IX) |
| 复制到 | 意向独占 (IX) |
| DDL | |
| 创建表格 | 架构修改(Sch-M) |
| ALTER TABLE | 模式修改(Sch-M) |
| DROP TABLE | Schema-修改(Sch-M) |
| TRUNCATE TABLE | Schema-Modification(Sch-M) |
| 创建表以选择 | Schema-Modification(Sch-M) |
| 创建表作为克隆 | 模式修改(Sch-M) |
可以使用动态管理视图 (DMV) sys.dm_tran_locks 查询当前持有的锁。
有关锁、锁升级和锁兼容性的详细信息,请参阅 事务锁定和行版本控制指南。
快照隔离
Fabric 数据仓库对所有事务强制实施快照隔离。 快照隔离是一种基于行的隔离级别,它为数据提供事务级的一致性,并使用存储在 tempdb 中的行版本来选择要更新的行。 该事务使用事务开始时存在的数据行版本。 这可确保每个事务在与事务开始时的数据一致的一致性快照上进行操作。
在快照隔离中,事务中的查询会依据事务开始时的数据库状态查看相同的版本或快照。 在快照隔离中,修改数据的事务不会阻止读取数据的事务,而读取数据的事务不会阻止写入数据的事务。 这种乐观的非阻塞行为也大大减少了复杂事务的死锁的可能性。
如果使用 T-SQL 更改隔离级别,则会在查询执行时忽略更改,并应用快照隔离。
在快照隔离中,可以进行写入或更新冲突,有关详细信息,请参阅 了解 Fabric 数据仓库中的写入-写入冲突。
模式锁
架构锁可防止 DDL 语句发生冲突,例如在事务中更新行时更改表的架构。 请注意,DDL操作,例如架构更改和迁移,可能会阻止或被正在进行的读取负载所阻止。
- 在数据定义语言(DDL)操作期间,数据库引擎使用模式修改(
Sch-M)锁。 在锁被持有期间,Sch-M该锁会阻止对表的所有并发访问,直到释放锁。 - 在数据作语言(DML)作期间,数据库引擎使用架构稳定性 (
Sch-S) 锁。 获取Sch-M锁的操作会被Sch-S锁阻止。 在编译查询时,其他事务会继续运行,但 DDL 操作会被阻止,直到它们能够获得对架构的独占访问权限。 - 在事务持续期间,DDL操作还会在与目标表关联的系统视图中的行上获取一个排他锁(
X),例如sys.tables和sys.objects。 这会阻止SELECT、sys.tables和sys.objects上的并发语句。
避免阻止的最佳做法
- 避免长时间运行的事务,或在并发活动较少或没有的期间进行计划。
- 仅在维护窗口期间安排DDL操作,以将阻塞降至最低。
- 避免在显式用户事务中放置 DDL 语句(
BEGIN TRAN)。 修改表的长时间运行事务可能会对用户表及类似sys.tables的系统目录视图上的其他DML操作和SELECT查询造成阻塞问题。 若要监视和排查潜在的锁冲突,请使用sys.dm_tran_locks。 - 监控仓库中的锁定和冲突。
- 使用 sys.dm_tran_locks 检查当前锁。
- Fabric 数据仓库支持用户定义的事务中的某些 DDL 语句,但在长时间运行的事务中不建议这样做。 在事务中,DDL 语句可能阻止并发事务或导致写-写冲突。
了解 Fabric 数据仓库中的写入-写入冲突
当两个事务尝试UPDATE、DELETE、MERGE或TRUNCATE同一个表时,可能会发生写入-写入冲突。
写入冲突或更新冲突可能发生在表级别,因为 Fabric 数据仓库使用表级锁定。 如果两个事务尝试修改同一表中的不同行,它们也可能发生冲突。
写写冲突主要来自两种情况:
- 用户引发的工作负荷冲突
- 多个用户或进程同时修改同一个表。
- 可以在 ETL 管道、批处理更新或重叠事务中发生。
- 系统引发的冲突
- 后台系统任务(如自动数据重整)会重写质量不佳的文件。
- 这些可能会与用户事务冲突,尽管数据压缩抢占会主动阻止此类型的写写冲突。
如果发生写写冲突,你可能会看到错误消息,例如:
- 错误 24556:由于更新冲突导致快照隔离事务中止。 使用快照隔离在数据库 '%.*ls' 中直接或间接访问表 '%.*ls' 时,如果该表中的行已被另一个并发事务删除或更新,则可能导致更新冲突。 请重试该事务。
- 错误 24706:由于更新冲突而中止的快照隔离事务。 不能使用快照隔离在数据库 '%.*ls' 中直接或间接访问表 '%.*ls' 来更新、删除或插入已由另一个事务修改或删除的行。 请重试事务。
如果遇到这些错误消息,一个或多个事务成功,并且一个或多个冲突的事务失败。 重试失败的交易。
注释
即使MERGE事务仅导致追加更改,它们仍然会导致写写冲突。 当事务影响与其他并发 DML 事务不同的行时 MERGE ,如果 MERGE 不是第一个提交事务,则可能会遇到此错误:“由于更新冲突而中止的快照隔离事务”。
避免写入-写入冲突的最佳做法
为了避免写写冲突:
- 避免在同一个表上同时执行
UPDATEDELETEMERGE操作。- 请特别注意多步骤事务中的
UPDATE,DELETE,MERGE操作。
- 请特别注意多步骤事务中的
- 在所有应用程序和查询中使用重试逻辑。
- 在存储过程和 ETL 管道中实现重试逻辑。
- 在管道或应用中添加延迟的重试逻辑,以处理暂时性冲突。
- 使用指数退避策略来避免重试风暴加剧暂时性网络中断。 有关详细信息,请参阅 重试模式。
- 可能与 Fabric Data Warehouse 背景数据压缩服务发生写入-写入冲突,但通常会由 数据压缩预防 功能阻止。
表和 Parquet 文件锁定
更新表中的一行或多行的两个或多个并发事务产生的冲突将在事务结束时进行评估。 要提交的第一个事务将成功完成,其他事务将回滚并返回错误。 这些冲突在表级别而不是单个 parquet 文件级别进行评估。
INSERT 语句始终会创建新的 parquet 文件,这意味着与其他事务(DDL 除外)的冲突更少,因为表的架构可能会更改。
限制
- 不支持分布式事务,例如
BEGIN DISTRIBUTED TRANSACTION。 -
ALTER TABLE在显式事务中不受支持。 - 不支持保存点。
- 不支持命名事务。
- 不支持标记事务。
- 目前,仓库中的 T-SQL 功能有限。 有关目前无法使用的 T-SQL 命令列表,请查看 Fabric 数据仓库中的 T-SQL 功能区域。
- 如果事务将数据插入空表并在回滚前发出 SELECT,则自动生成的统计信息仍可能反映未提交的数据,从而导致统计信息不准确。 不准确的统计信息可能导致查询计划和执行时间未优化。 如果在大型 INSERT 之后使用 SELECT 回滚事务,则请更新 SELECT 中提到的列的统计信息。