Sql Server Snapshot和mysql MVCC

本文详细介绍了SQL Server中的事务隔离级别,包括读已提交、可重复读等,并对比了MySQL InnoDB的隔离级别特性。阐述了MVCC机制如何减少锁的开销并提高并发能力。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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降低了锁开销,提高了并发能力。非锁定读。
### MySQL MVCC 并发控制机制的区别 MySQL 是一个完整的数据库管理系统,它通过多种机制来实现并发控制,包括锁机制多版本并发控制(MVCC)。MVCCMySQL 中用于实现并发控制的一种技术,尤其在 InnoDB 存储引擎中得到了广泛应用。两者之间的区别主要体现在以下几个方面: #### 1. **作用范围不同** MySQL 提供了多种并发控制机制,包括表锁、行锁、间隙锁等,这些机制可以用于不同的场景,例如写操作通常需要加锁来保证数据一致性。而 MVCC 仅用于实现读操作的并发控制,它通过为数据行维护多个版本来避免读操作阻塞写操作,从而提高并发性能。这种机制主要适用于 `REPEATABLE READ` `READ COMMITTED` 隔离级别,在 `READ UNCOMMITTED` `SERIALIZABLE` 隔离级别下不适用 [^3]。 #### 2. **实现方式不同** MySQL 的并发控制可以通过锁机制实现,例如行锁、表锁间隙锁等。这些锁机制会直接对数据进行锁定,以防止其他事务对数据进行修改。而 MVCC 的实现方式完全不同,它通过为数据行维护多个版本来实现并发控制。每个事务在读取数据时,可以看到一个特定版本的数据快照,这样可以避免读操作等待写操作释放锁,从而提高并发性能 [^2]。 #### 3. **适用场景不同** MySQL 的锁机制适用于需要高数据一致性的场景,例如写操作较多的事务。在这种情况下,锁机制可以确保数据的一致性,但可能会降低并发性能。而 MVCC 更适合读操作较多的场景,它通过快照读(Snapshot Read)实现非阻塞读操作,从而提高并发性能。快照读的前提是隔离级别不是 `SERIALIZABLE`,在该隔离级别下,快照读会退化为当前读(Current Read) [^4]。 #### 4. **对隔离级别的支持不同** MySQL 的锁机制可以支持所有四种隔离级别:`READ UNCOMMITTED`、`READ COMMITTED`、`REPEATABLE READ` `SERIALIZABLE`。而 MVCC 仅支持 `REPEATABLE READ` `READ COMMITTED` 两种隔离级别。在 `READ UNCOMMITTED` 隔离级别下,总是读取最新的数据行,而不是符合当前事务版本的数据行,因此不支持 MVCC。而在 `SERIALIZABLE` 隔离级别下,会对所有读取的行加锁,因此也不支持 MVCC [^3]。 #### 5. **性能影响不同** MySQL 的锁机制可能会导致锁竞争,尤其是在高并发环境下,这可能会降低系统的性能。而 MVCC 通过快照读避免了加锁操作,从而降低了开销。然而,MVCC 需要维护数据的多个版本,这可能会增加存储内存的开销 [^4]。 ### 示例代码:查看 MySQL 隔离级别 以下是一个简单的 SQL 示例,用于查看当前会话的隔离级别: ```sql -- 查看当前会话的隔离级别 SELECT @@tx_isolation; ``` ### 示例代码:设置 MySQL 隔离级别 以下是一个简单的 SQL 示例,用于设置当前会话的隔离级别为 `REPEATABLE READ`: ```sql -- 设置当前会话的隔离级别为可重复读 SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ; ``` ### 总结 MySQL MVCC 在并发控制方面各有特点。MySQL 提供了多种并发控制机制,包括锁机制 MVCC,适用于不同的场景。而 MVCCMySQL 中用于实现并发控制的一种技术,特别适合读操作较多的场景。两者在作用范围、实现方式、适用场景、对隔离级别的支持以及性能影响等方面存在显著区别。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值