Sql Server Snapshot和mysql MVCC
mysql
在一个事务A中插入一条数据
在B事务中查询到的还是以前的数据,可以select *from table,不被锁住
Sql Server 默认级别 读已提交
所以A事务在 X表插入数据,在未提交的情况下,则B事务无法做 包含A事务新数据的 操作。
具体地说 B事务无法做全量的数据查询,
B事务也无法单条查询新数据行
B事务可以查询其他数据行
B事务依然可以插入新数据
B事务不能查询count
如果最新的数据是B事务插入的 B事务可以查询maxId,如过最新数据为A插入 那么A事务可以查询maxid 而不用等待锁。
B事务加With (nolock) 可以查询A事务中的新增行 也可以查询count。这是脏读
A事务在 X表更新数据行,则B事务也无法做 关于A事务所操作的数据行 的查询,可操作其他行
B事务也不能更新刚刚A事务操作的数据行、
B事务不能查询count
B事务可以查询max
由于默认级别是读已提交,所以存在不可重复读的问题。两次查询的单行和多行数据可能会不同。
下面创建新数据库 并开启MVCC的情况:
ALTER DATABASE testdb3 SET allow_snapshot_isolation ON
ALTER DATABASE testdb3 SET READ_COMMITTED_SNAPSHOT ON
开启SNAPSHOT后,上述需要加with nolock才能查询的数据,不再需要nolock了,并且MVCC机制保障了我们不会有脏读。
但是当前并非可重复读级别,幻读依然存在。必须要说,我觉得与其称为幻读,不如叫做幻行。
下面说说SqlServer可重复读级别,当一个数据库连接A 的事务隔离设置为此级别。
如果A已经查询过数据行X,那么B事务对X的修改要等A事务结束。这就保证了在一次事务A中,多次查询同一条数据结果是相同的。
注意SqlServer在此隔离级别下,即使加上快照,也无法避免幻读. 此快照就算MVCC机制
但是mysql innodb 隔离级别默认为可重复读,并且其MVCC机制,可以避免幻读。
总之mvcc降低了锁开销,提高了并发能力。非锁定读。