读未提交
- 两个事务都开启事务,事务1
insert
了一条数据,但是未提交事务,另外一个事务能够读取到事务1未提交事务修改的数据,当事务1回滚,则事务2就会产生脏读,这是数据库最低的隔离级别,一般不采用。
读已提交
- 两个事务都开启事务,事务1开启事务insert了一条数据,提交事务,另外一个事务不能够读取到事务1未提交事务,能够读取到事务1提交事务修改的数据。
可重复读
- 两个事务都开启事务,事务2查询了全表有12条数据,事务1开启事务
insert
了一条数据,修改了其中某一条数据,提交事务,事务2再次查询表,还是12条数据,并且数据没有做任何改动,即该隔离级别每次读取出来的数据都是一样的。但是事务1将表里的数据全部更新,发现更新了13条,即产生了幻读。当插入一条跟事务1同意的数据时发现此记录已存在,无法插入,此时也发生了幻读。
(1)事务2开启事务查询的表数据情况:
(2)事务1开启事务插入了一条数据,并修改了一条数据,做了事务提交:
(3)事务2在该事务下再次查询,还是查不到事务1的修改和插入
串行化
隔离级别 | 脏读(Dirty Read) | 不可重复读(NonRepeatable Read) | 幻读(Phantom Read) |
---|---|---|---|
读未提交(Read uncommitted) | 可能 | 可能 | 可能 |
读已提交(Read committed) | 不可能 | 可能 | 可能 |
可重复读(Repeatable read) | 不可能 | 不可能 | 可能 |
串行化(Serializable ) | 不可能 | 不可能 | 不可能 |
mysql默认的隔离级别:可重复读
Oracle默认的隔离级别:读已提交
补充:
幻读:并不是说两次读取获取的结果集不同,幻读侧重的方面是某一次的 select 操作得到的结果所表征的数据状态无法支撑后续的业务操作。更为具体一些:1、select 某记录是否存在,不存在,准备插入此记录,但执行 insert 时发现此记录已存在,无法插入,此时就发生了幻读。2、select 某记录是否存在,不存在,准备批量更新记录,但执行 update时发现此记录也被更新了,多更新了本没查到的数据,产生了幻读。
select * from xxx forupdate 有索引就锁索引 无索引锁表