首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >“已提交读”和“可重复读”的区别

“已提交读”和“可重复读”的区别
EN

Stack Overflow用户
提问于 2010-10-27 23:35:35
回答 8查看 162.5K关注 0票数 299

我认为上面的隔离级别是如此相似。有没有人能举几个很好的例子来描述一下主要的区别是什么?

EN

回答 8

Stack Overflow用户

回答已采纳

发布于 2010-10-28 01:44:53

read committed是一个隔离级别,它保证在读取时任何读取的数据都已提交。它只是限制读者看到任何中间的、未提交的、“脏的”读取。它没有任何承诺,如果事务重新发出读取,将找到相同的数据,数据在读取后可以自由更改。

可重复读取是一种更高的隔离级别,除了保证读取提交级别外,它还保证任何读取的数据都不能更改,如果事务再次读取相同的数据,它将发现以前读取的数据在适当的位置,未更改,并且可供读取。

下一个隔离级别serializable提供了更强大的保证:除了可重复读取保证的所有内容外,它还保证后续读取不会看到新的数据。

假设您有一个表T,其中有一列C,其中有一行,假设它的值为'1‘。假设您有一个简单的任务,如下所示:

代码语言:javascript
复制
BEGIN TRANSACTION;
SELECT * FROM T;
WAITFOR DELAY '00:01:00'
SELECT * FROM T;
COMMIT;

这是一个简单任务,从表T发出两次读取,两次读取之间的延迟为1分钟。

  • 在READ COMMITTED下,第二次SELECT可能返回任何数据。并发事务可以更新记录、删除记录、插入新记录。第二次select将始终看到新数据。
  • 在REPEATABLE READ下,第二次SELECT保证至少显示第一次SELECT返回的未更改的行。并发事务可以在这一分钟内添加新行,但不能删除或更改现有行。SERIALIZABLE reads下的
  • 保证看到与第一个select完全相同的行。并发事务不能更改或删除任何行,也不能插入新行。

如果你遵循上面的逻辑,你会很快意识到SERIALIZABLE事务,虽然它们可能会让你的生活变得容易,但总是完全阻塞每一个可能的并发操作,因为它们要求任何人都不能修改、删除或插入任何行。.Net System.Transactions作用域的默认事务隔离级别是可序列化的,这通常解释了导致的糟糕性能。

最后,还有快照隔离级别。快照隔离级别提供了与可序列化相同的保证,但不要求任何并发事务都不能修改数据。相反,它迫使每个读者看到自己版本的世界(它自己的“快照”)。这使得编程非常容易,而且不会阻塞并发更新,因此具有很高的可扩展性。然而,这种好处是有代价的:额外的服务器资源消耗。

补充说明:

  • Isolation Levels in the Database Engine
  • Concurrency Effects
  • Choosing Row Versioning-based Isolation Levels
票数 677
EN

Stack Overflow用户

发布于 2013-01-18 15:23:13

可重复读取

数据库的状态是从事务开始时维护的。如果在session1中检索一个值,然后在session2中更新该值,那么在session1中再次检索它将返回相同的结果。读取是可重复的。

代码语言:javascript
复制
session1> BEGIN;
session1> SELECT firstname FROM names WHERE id = 7;
Aaron

session2> BEGIN;
session2> SELECT firstname FROM names WHERE id = 7;
Aaron
session2> UPDATE names SET firstname = 'Bob' WHERE id = 7;
session2> SELECT firstname FROM names WHERE id = 7;
Bob
session2> COMMIT;

session1> SELECT firstname FROM names WHERE id = 7;
Aaron

已提交读取

在事务上下文中,您将始终检索最近提交的值。如果您在session1中检索一个值,在session2中更新它,然后在session1again中检索它,那么您将获得在session2中修改过的值。它读取最后提交的行。

代码语言:javascript
复制
session1> BEGIN;
session1> SELECT firstname FROM names WHERE id = 7;
Aaron

session2> BEGIN;
session2> SELECT firstname FROM names WHERE id = 7;
Aaron
session2> UPDATE names SET firstname = 'Bob' WHERE id = 7;
session2> SELECT firstname FROM names WHERE id = 7;
Bob
session2> COMMIT;

session1> SELECT firstname FROM names WHERE id = 7;
Bob

合乎道理?

票数 77
EN

Stack Overflow用户

发布于 2016-07-29 11:53:16

根据我对这个帖子和@remus-rusanu的阅读和理解,简单的答案是基于这个简单的场景:

有两个事务A和B。事务B正在读表X,事务A正在写表X,事务B再次在表X中读。

  • ReadUncommitted:事务B可以从事务A读取未提交的数据,并且可以根据B的写入看到不同的行。all
  • ReadCommitted:事务B上的没有锁只能从事务A读取已提交的数据,并且它可以根据已提交的仅B写入看到不同的行。我们可以称它为简单的Lock?
  • RepeatableRead:,事务B将读取相同的数据(行),无论事务A正在做什么。但事务A可以更改其他行。Block
  • Serialisable:事务B将读取与以前相同的行,并且事务A无法在表中读取或写入行级别的事务B。表级Block
  • Snapshot:每个事务都有自己的副本,它们正在处理它。每一个都有自己的view
票数 41
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4034976

复制
相关文章

相似问题

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