二 最详细MySQL事务隔离级别及原理讲解!( 三 )


The default isolation level for InnoDB. It prevents any rows that are queried from being changed by other transactions, thus blocking non-repeatable reads but not phantom reads. It uses a moderately strict locking strategy so that all queries within a transaction see data from the same snapshot, that is, the data as it was at the time the transaction started.
InnoDB的默认隔离级别 。它可防止查询的任何行被其他事务更改,从而阻止不可重复的读取,但不会阻止幻读 。它使用中等严格的锁定策略,以便事务中的所有查询都可以查看来自同一快照的数据,即事务开始时的数据 。
看重点!RR隔离级别是InnoDB默认隔离级别,他可以解决不可重复读,但不能解决幻读!这就是为什么我说很多文章错了,官方已经给出了明确定义 。
mysql> set session transaction isolation level repeatable read;Query OK, 0 rows affected (0.00 sec)mysql> SELECT @@tx_isolation;+-----------------+| @@tx_isolation|+-----------------+| REPEATABLE-READ |+-----------------+1 row in set, 1 warning (0.00 sec)如表格所示,不可重复读是被解决了,但很明显还有一个问题,没有解决幻读 。
事务A事务B
二 最详细MySQL事务隔离级别及原理讲解!

文章插图
 

二 最详细MySQL事务隔离级别及原理讲解!

文章插图
 

二 最详细MySQL事务隔离级别及原理讲解!

文章插图
 

二 最详细MySQL事务隔离级别及原理讲解!

文章插图
 
已解决不可重复读
此时我们再来一次,回到B事务提交前但状态,执行一条insert语句 。
二 最详细MySQL事务隔离级别及原理讲解!

文章插图
 

二 最详细MySQL事务隔离级别及原理讲解!

文章插图
 
回到更新前状态 。
在B事务执行 insert 后再次查询
二 最详细MySQL事务隔离级别及原理讲解!

文章插图
 

二 最详细MySQL事务隔离级别及原理讲解!

文章插图
 
B事务提交后出现了奇怪的情况 。A事务查询到的数据前后一致,但是在UPDATE条件下符合的数据却变成两条 。
二 最详细MySQL事务隔离级别及原理讲解!

文章插图
 
A row that Appears in the result set of a query, but not in the result set of an earlier query. For example, if a query is run twice within a transaction, and in the meantime, another transaction commits after inserting a new row or updating a row so that it matches the WHERE clause of the query.
在查询的结果集中出现的行,但在较早的查询的结果集中没有出现 。例如,如果一个查询在一个事务中运行两次,同时,另一个事务将在插入新行或更新一行以使其与查询的WHERE子句匹配之后提交 。
请看上方幻读定义 。重点是,同样的条件同一事务前后结果中出现了和之前不一样的行 。与不可重复读的区别是什么:幻读的条件也符合不可重复读,但是不可重复读不一定符合幻读 。前后检索出不一样的行当然查询前后查询结果不同,但是查询结果不同不一定有新的行 。
为什么很多文章错误的认为RR可以解决幻读呢?我也不知道,可能是被快照读迷惑了?MVCC能解决快照读下的幻读问题,但是没法保证当前读下的幻读问题(这个我们下一篇细说,内容太多了) 。但是幻读确实在一定条件下解决,这个条件就是 next-key locks 。
By default, InnoDB operates in REPEATABLE READ transaction isolation level. In this case, InnoDB uses next-key locks for searches and index scans, which prevents phantom rows
默认情况下,InnoDB以REPEATABLE READ事务隔离级别运行 。在这种情况下,InnoDB使用next-key locks 锁定进行搜索和索引扫描,从而防止幻读
使用效果如下:
select count(*) from test where id>=9 lock in share mode;
二 最详细MySQL事务隔离级别及原理讲解!

文章插图
 
执行 insert 发生阻塞,如此便使用了 next-key locks 防止幻读 。
锁原理:
1.事务A在读取某数据时,必须先对其加共享锁,直到事务结束才释放(注意是事务结束才释放)
2.事务A在更新某数据时,必须先对其加排他锁,直到事务结束才释放(注意是事务结束才释放)
 4、串行读(SERIALIZABLE_READ)
The isolation level that uses the most conservative locking strategy, to prevent any other transactions from inserting or changing data that was read by this transaction, until it is finished. This way, the same query can be run over and over within a transaction, and be certain to retrieve the same set of results each time. Any attempt to change data that was committed by another transaction since the start of the current transaction, cause the current transaction to wait.


推荐阅读