事务期间数据库读取数据如何变化?

Ran*_*ron 3 sql database transactions

让我们假设以下场景:

[Start TX]
SELECT userName FROM users WHERE userId = 1; -- returns x
UPDATE users SET userName = 'y' where userId = 1;
SELECT userName FROM users WHERE userId = 1; -- returns y
[End TX]
Run Code Online (Sandbox Code Playgroud)

数据库如何知道第二次返回 y ?事务状态如何集成到查询处理中?

另一个场景:

[Start TX]
SELECT userName FROM users, accounts WHERE useres.userId = accounts.userId AND accounts.balance < 0; -- returns x
UPDATE accounts SET balance = 100 where userId = 1;
SELECT userName FROM users, accounts WHERE useres.userId = accounts.userId AND accounts.balance < 0; -- returns nothing
[End TX]
Run Code Online (Sandbox Code Playgroud)

同样的问题 - 数据库如何在事务信息上运行连接?

Dew*_*wfy 5

让我们将数据库表视为B-Tree。让我谈谈它的数据结构——我们应该知道的关于 B 树是页面组织的主题。假设您有 9 行(标记为A..I)和页面大小为 3 的 B 树。以某种方式我们在磁盘上有 3 页

Page1: A,B,C,
Page2: D,E,F
Page3: G,H,I
Run Code Online (Sandbox Code Playgroud)

假设您更改了 row 中的某些内容E。您的数据库连接将为 page2 分配内存并完全加载它 ( D..F)。您进行了更改,E但未提交事务。现在您尝试选择(在同一连接中)。由于内存已经包含加载的页面,您的 SELECT 将看到被修改的数据。但是如果另一个连接将尝试加载E它必须加载到内存中的可变D..Fpage2。提交 page2 后持久化,所以所有其他连接都可以看到更改。

当然,在现实世界中,这个过程要复杂得多。