首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如果两个事务都不回滚,则读取已提交的vs

如果两个事务都不回滚,则读取已提交的vs
EN

Stack Overflow用户
提问于 2019-01-06 15:39:31
回答 4查看 3.6K关注 0票数 4

我正在努力理解读取、提交和未提交的隔离级别。我知道理论上读未提交允许脏读和读提交不允许,但我仍然不能真正理解。

考虑到上面的数字,如果没有一个事务被中止,那么最终的结果对于读提交和读未提交都是一样的吗?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2019-01-06 15:55:51

如果您使用读提交的隔离级别,T2需要在步骤4中等待T1完成并提交其工作。此外,步骤6中的T1无法找到带Maria%的Nome,因此删除0行。

但是在读未提交的隔离级别上,可以同时执行读/写操作。

结果用于读取提交的隔离级别,

代码语言:javascript
复制
Pessoas (Jaoa Silva, 96.....)
Pessoas (Maria Fon..., 9199...)
Pessoas (Joao Manuel Silva, 9699...)

对于读未提交的隔离级别,则为

代码语言:javascript
复制
Pessoas (Joao Manuel Silva, 9699...)
票数 -1
EN

Stack Overflow用户

发布于 2019-01-07 10:39:06

您的示例与Isolation Levels无关。这是因为它们影响readers行为,而不是writers,在您的示例中只有writers

您应该参考这篇BOL文章:了解隔离级别,它说

选择事务隔离级别不会影响为保护数据修改而获得的锁。事务总是对它修改和保存的任何数据获得独占锁,直到事务完成为止,而不管为该事务设置的隔离级别如何。For 读取操作事务隔离级别主要定义保护级别,使其免受其他事务修改的影响。

在您的示例中,没有一个事务是read,它们都是modify。第一个事务将在感兴趣的RIDkey (如果它是堆表或群集表)上获得RIDkey(如果它是堆表或群集表) --我以后将称之为res_1 --用于插入事务,并在事务的所有时间内保存它(对应的pageobject上也有IX ),第二个事务的第一个语句也是如此:当插入时,它将在E 126res_2E 227/code>上获得X。

在DELETE尝试中,第二个事务将被阻塞,因为它无法获得X (如果在where条件下没有索引),这是因为在第一个事务持有的同一资源(res_1)上已经存在X。第二个事务中没有第二个INSERT,因为以前的DELETE被阻塞了。

最后,当第一个事务尝试它的DELETE时,它需要res_2上的X或U (取决于索引的存在),但是它已经被tran2用X阻塞了,所以它也被阻塞了,并且没有退出这种情况,每个会话等待另一个会话完成,没有会话能够完成,此时发生deadlock,服务器将通过rolling back解决它--事务之一。

票数 6
EN

Stack Overflow用户

发布于 2019-01-06 16:07:57

读取未提交的数据允许读取其他事务未提交的脏数据。Server引擎忽略正在读取的表下的任何锁,并直接从内存读取数据。

READ将读取已经提交的数据,但如果数据受到其他事务的影响,则会等待。

因此,在提供系统的示例中,系统不仅正在读取,而且还试图删除仍未提交的行,因此,两者都将等待其他事务完成,该示例是死锁的典型示例。

为了缓和已提交与未提交之间的差异,我将向您展示一个简单而明确的示例,我们将在这两种模式下运行两次。

代码语言:javascript
复制
-- Query Window 1
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;  -- Prepare for first Run
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;    -- Prepare for second Run

BEGIN TRANSACTION                                   -- Step 1
INSERT INTO Audit (ProductID, PrevValue, NewValue, ChangedBy)   
    VALUES (1, 'AAA', 'aaa', SYSTEM_USER);          -- Step 3
COMMIT TRANSACTION                                  -- Step 5

-- Query Window 2
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;  -- Prepare for first Run
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;    -- Prepare for second Run

BEGIN TRANSACTION                           -- Step 2
SELECT * FROM Audit WHERE PrevValue = 'AAA' -- Step 4
COMMIT TRANSACTION                          -- Step 6

我们必须先在两个查询中运行未提交级别的行,然后转到第一个,运行步骤1,转到第二个,步骤2,等等。在未提交时,当我们运行步骤4时,我们将在执行脏读取时(从内存中)立即看到结果。对于第二次运行,我们将首先使用以下方法删除行测试:

代码语言:javascript
复制
DELETE FROM Audit WHERE PrevValue LIKE 'AAA';   

然后,将在两个查询窗口中运行提交级别的行,并运行相同的序列。我们现在将观察到,当我们运行步骤4时,系统仍然没有响应。就在我们运行步骤5提交insert的那一刻,窗口将显示结果。

我希望现在的问题更清楚。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54063118

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档