我认为上述隔离级别是如此相似。有人能举个例子说明一下主要的区别是什么吗?


当前回答

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

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

ReadUncommitted: Transaction B can read uncommitted data from Transaction A and it could see different rows based on B writing. No lock at all ReadCommitted: Transaction B can read ONLY committed data from Transaction A and it could see different rows based on COMMITTED only B writing. could we call it Simple Lock? RepeatableRead: Transaction B will read the same data (rows) whatever Transaction A is doing. But Transaction A can change other rows. Rows level Block Serialisable: Transaction B will read the same rows as before and Transaction A cannot read or write in the table. Table-level Block Snapshot: every Transaction has its own copy and they are working on it. Each one has its own view

其他回答

可重复读取

数据库的状态从事务开始时开始维护。如果在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中更新它,然后再次在session1中检索它,您将得到在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

有道理吗?

这个老问题已经有了一个公认的答案,但我喜欢从如何改变SQL Server中的锁定行为的角度来考虑这两个隔离级别。这可能对那些像我一样调试死锁的人有帮助。

READ COMMITTED(默认)

共享锁在SELECT语句中获取,然后在SELECT语句完成时释放。这就是系统如何保证没有未提交数据的脏读。其他事务仍然可以在SELECT完成之后和事务完成之前更改基础行。

可重复读取

在SELECT中获取共享锁,然后仅在事务完成后才释放共享锁。这就是系统如何保证您读取的值在事务期间不会更改(因为它们在事务完成之前保持锁定)。

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

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

ReadUncommitted: Transaction B can read uncommitted data from Transaction A and it could see different rows based on B writing. No lock at all ReadCommitted: Transaction B can read ONLY committed data from Transaction A and it could see different rows based on COMMITTED only B writing. could we call it Simple Lock? RepeatableRead: Transaction B will read the same data (rows) whatever Transaction A is doing. But Transaction A can change other rows. Rows level Block Serialisable: Transaction B will read the same rows as before and Transaction A cannot read or write in the table. Table-level Block Snapshot: every Transaction has its own copy and they are working on it. Each one has its own view

请注意,repeatable read中的repeatable针对的是一个元组,而不是整个表。在ANSC隔离级别中,可能会发生幻象读取异常,这意味着使用相同的where子句读取表两次可能返回不同的返回不同的结果集。从字面上看,这是不可重复的。

我对初始接受解的观察。

在RR下(默认mysql) -如果一个tx是打开的,一个SELECT已经被触发,另一个tx不能删除属于前一个READ结果集的任何行,直到前一个tx被提交(事实上,新的tx中的delete语句会挂起),然而下一个tx可以毫无麻烦地删除表中的所有行。顺便说一下,上一个tx中的下一次READ仍然会看到旧数据,直到它被提交。