小编Ste*_*eve的帖子

单语句事务一致性

前几天我在 StackOverflow 上遇到了这个问答。引用问题作者的评论,情况似乎“有些可怕”。本次问答中也设置了类似的情况。

我的经验法则一直是 SQL 中的单个语句“原子地”执行。也就是说,在任何默认配置下,成功执行的单个语句(即没有死锁或中止)不存在任何潜在的并发问题。

然而我链接的两个问答表明并非如此。

说明问题的最基本场景似乎是这种自连接:

SELECT
     t1.*
    ,t2.*

FROM 
    some_table AS t1

FULL OUTER JOIN 
    some_table AS t2
    ON t2.id = t1.id
Run Code Online (Sandbox Code Playgroud)

是否存在不需要t1与 完全一致的情况t2,因此此查询可能会在全连接的一侧或另一侧返回 NULL,因为 t1 的数据与 t2 的数据是在不同的时间获取的因此每个可能引用不同的数据(即使它是在单个语句中引用的同一个表)?

我的假设始终是单个语句(引用多个表,或多次引用某些表)在某个时间步骤获取它所需的所有数据,作为数据库的单个一致快照。如果隔离级别为READ COMMITTED,那么我假设快照是单个语句开始时所有已提交数据的快照。

我对 RCSI 功能的理解是,它将这种假定的快照保证扩展到多语句事务。

我很震惊(虽然并不完全惊讶)发现事实似乎并非如此,而且我多年来的基本理解似乎被颠覆了。

有关这方面的信息似乎非常少。正如2014 年这篇文章的作者所说,这种行为似乎“甚至能够误导经验丰富的数据库从业者”。

该文章表明,即使是非常常见的 SELECT 查询样式似乎也能够在执行过程中修改其基础数据,并返回违反 WHERE 子句的显式逻辑标准的结果。这种行为方式可能成为默认行为,这似乎很荒谬。

问题

Microsoft(或 SQL 标准)是否有任何信息明确指定并确认此行为?

为了保证单个语句相当于所有数据的单个一致快照,需要进行哪些设置(在会话级别或语句级别)?

sql-server transaction isolation-level

-1
推荐指数
1
解决办法
137
查看次数

标签 统计

isolation-level ×1

sql-server ×1

transaction ×1