我认为上面的隔离级别是如此相似。有没有人能举几个很好的例子来描述一下主要的区别是什么?
发布于 2010-10-28 01:44:53
read committed是一个隔离级别,它保证在读取时任何读取的数据都已提交。它只是限制读者看到任何中间的、未提交的、“脏的”读取。它没有任何承诺,如果事务重新发出读取,将找到相同的数据,数据在读取后可以自由更改。
可重复读取是一种更高的隔离级别,除了保证读取提交级别外,它还保证任何读取的数据都不能更改,如果事务再次读取相同的数据,它将发现以前读取的数据在适当的位置,未更改,并且可供读取。
下一个隔离级别serializable提供了更强大的保证:除了可重复读取保证的所有内容外,它还保证后续读取不会看到新的数据。
假设您有一个表T,其中有一列C,其中有一行,假设它的值为'1‘。假设您有一个简单的任务,如下所示:
BEGIN TRANSACTION;
SELECT * FROM T;
WAITFOR DELAY '00:01:00'
SELECT * FROM T;
COMMIT;这是一个简单任务,从表T发出两次读取,两次读取之间的延迟为1分钟。
如果你遵循上面的逻辑,你会很快意识到SERIALIZABLE事务,虽然它们可能会让你的生活变得容易,但总是完全阻塞每一个可能的并发操作,因为它们要求任何人都不能修改、删除或插入任何行。.Net System.Transactions作用域的默认事务隔离级别是可序列化的,这通常解释了导致的糟糕性能。
最后,还有快照隔离级别。快照隔离级别提供了与可序列化相同的保证,但不要求任何并发事务都不能修改数据。相反,它迫使每个读者看到自己版本的世界(它自己的“快照”)。这使得编程非常容易,而且不会阻塞并发更新,因此具有很高的可扩展性。然而,这种好处是有代价的:额外的服务器资源消耗。
补充说明:
发布于 2013-01-18 15:23:13
可重复读取
数据库的状态是从事务开始时维护的。如果在session1中检索一个值,然后在session2中更新该值,那么在session1中再次检索它将返回相同的结果。读取是可重复的。
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中修改过的值。它读取最后提交的行。
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合乎道理?
发布于 2016-07-29 11:53:16
根据我对这个帖子和@remus-rusanu的阅读和理解,简单的答案是基于这个简单的场景:
有两个事务A和B。事务B正在读表X,事务A正在写表X,事务B再次在表X中读。
https://stackoverflow.com/questions/4034976
复制相似问题