为什么默认设置rr?:
隔离级别\解决问题 | 脏读 | 不可重复读 | 幻读 |
---|---|---|---|
读未提交 | O | O | O |
读提交 | ❌ | O | O |
重复读 | ❌ | ❌ | |
序列化 | ❌ | ❌ | ❌ |
脏读:
某个事务已更新一份数据,另一个事务在此时读取了 同一份数据,由于某些原因,前一个RollBack操作了操作,则后一个事务所 读取的数据就会是不正确的。
不可重复读:
一个事务的两次查询之中数据不一 致,这可能是两次查询过程中间插入了一个**事务更新**的原有的数据
幻读(Phantom Read):
在一个事务的两次查询中数据笔数不一致,例如有 一个事务查询了几列(Row)数据,而另一个事务却在此时插入了新的几 列数据,先前的事务在接下来的查询中,就会发现有几列数据是它先前 所没有的。
Read Uncommitted(读取未提交内容) RU
在该隔离级别,所有事务都可以看到其他未提交事务的执行结果。本隔离级别 很少用于实际应用,因为它的性能也不比其他级别好多少。读取未提交的数 据,也被称之为脏读(Dirty Read)。
Read Committed(读取提交内容) RC
这是大多数数据库系统的默认隔离级别(但不是 MySQL 默认的)。它满足了 隔离的简单定义:一个事务只能看见已经提交事务所做的改变。这种隔离级别 也支持所谓的不可重复读(Nonrepeatable Read),因为同一事务的其他实例 在该实例处理其间可能会有新的 commit,所以同一 select 可能返回不同结果。
Repeatable Read(可重读) RR
这是 MySQL 的默认事务隔离级别,它确保同一事务的多个实例在并发读取数 据时,会看到同样的数据行。不过理论上,这会导致另一个棘手的问题:幻读 (Phantom Read)。简单的说,幻读指当用户读取某一范围的数据行时,另 一个事务又在该范围内插入了新行,当用户再读取该范围的数据行时,会发现 有新的“幻影” 行。InnoDB 和 Falcon 存储引擎通过多版本并发控制(MVCC, Multiversion Concurrency Control)机制解决了该问题。
mvcc相关
共享锁又称为读锁,简称S锁,顾名思义,共享锁就是多个事务对于同一数据可以共享一把锁,都能访问到数据,但是只能读不能修改。
排他锁又称为写锁,简称X锁,顾名思义,排他锁就是不能与其他所并存,如一个事务获取了一个数据行的排他锁,其他事务就不能再获取该行的其他锁,包括共享锁和排他锁,但是获取排他锁的事务是可以对数据就行读取和修改。
对于共享锁大家可能很好理解,就是多个事务只能读数据不能改数据,对于排他锁大家的理解可能就有些差别,我当初就犯了一个错误,以为排他锁锁住一行数据后,其他事务就不能读取和修改该行数据,其实不是这样的。排他锁指的是一个事务在一行数据加上排他锁后,其他事务不能再在其上加其他的锁。mysql InnoDB引擎默认的修改数据语句,update,delete,insert都会自动给涉及到的数据加上排他锁,select语句默认不会加任何锁类型,如果加排他锁可以使用select …for update语句,加共享锁可以使用select … lock in share mode语句。所以加过排他锁的数据行在其他事务种是不能修改数据的,也不能通过for update和lock in share mode锁的方式查询数据,但可以直接通过select …from…查询数据,因为普通查询没有任何锁机制。