MySQL的事务隔离级别包括四种,分别是读未提交、读提交、可重复读和串行化,以下是关于这些隔离级别以及脏读、幻读、不可重复读的详细介绍:
事务并发执行遇到的问题
- 脏读:指一个事务读到了另一个未提交事务修改过的数据。例如,会话A开启事务后将小王账户余额增加50但未提交,会话B此时读取小王账户余额为150,若会话A随后回滚,会话B读取到的150就是脏数据。
- 不可重复读:指在同一个事务内多次读取同一数据集合,但查到的结果却不相同。例如,会话A开启事务后第一次读取小王账户余额为100,会话B在另一个事务中将小王账户余额增加50并提交,会话A再次读取小王账户余额变为150,这就发生了不可重复读。
- 幻读:指当某个事务在读取某个范围内的记录时,另外一个事务又在该范围内插入了新的记录,当之前的事务再次读取该范围的记录时,会读取到之前没有读到的数据。例如,会话A开启事务后第一次查询余额为100的账户只有小王,会话B在另一个事务中插入了一个余额也为100的小张账户并提交,会话A再次查询余额为100的账户时,会读取到小王和小张两个账户,这就发生了幻读。
SQL标准制定的四种隔离级别
- 读未提交:一个事务还没提交时,它做的变更就能被别的事务看到。此级别下,脏读、不可重复读和幻读都可能发生。
- 读提交:一个事务提交之后,它做的变更才会被其他事务看到。此级别下,不可重复读和幻读可能发生,但脏读不会发生。
- 可重复读:一个事务执行过程中看到的数据,总是跟这个事务在启动时看到的数据是一致的。此级别下,幻读可能发生,但脏读和不可重复读不会发生。
- 串行化:对于同一行记录,“写”会加“写锁”,“读”会加“读锁”。当出现读写锁冲突的时候,后访问的事务必须等前一个事务执行完成,才能继续执行。此级别下,脏读、不可重复读和幻读都不会发生。
MySQL对四种隔离级别的支持情况
MySQL InnoDB存储引擎支持上述四种隔离级别。与SQL标准不同的是,InnoDB在可重复读隔离级别下,使用Next-Key Lock锁的算法,避免了幻读的产生,即在此级别下已能完全保证事务的隔离性要求。