1.read uncommitted(读未提交): 在一个事务中读取到另一个事务还没有提交的数据——脏读。
演示:
首先修改事务的隔离级别:set session transaction isolation level read uncommitted;
客户端A:
客户端B:
客户端B还没有提交修改的数据,而客户端A却可以收到修改的数据,这就是脏读
2.Read committed(读已提交): 已经解决了脏读问题,在一个事务中只会读取另一个事务已提交的数据,这种情况会出现不可重复读的问题。就是:在事务中重复读数据,数据的内容是不一样的。
演示:
修改事务的隔离级别:set session transaction isolation level read committed;
客户端A:
客户端B:
这种情况会出现不可重复读的问题。就是:在事务中重复读数据,数据的内容是不一样的。
这样永远读到的都是最新的数据,这样也是有坏处的:举个例子吧,比如老板让公司财务计算一下公司开销,发现公司的电费是一直变化的,不是定格的,这样就永远计算不了公司的开销,这是就是不可重复读出现的问题
再举一个例子吧:编一个刷卡的场景吧,要付100块钱,你在一个事务里,select了一下某个帐号,发现它的余额100元足够,于是发起减余额的操作,做update XX set 余额=余额-100 where ....,结果在你update之前其它事务操作余额变成50了,update完变成-50了
3.repeatable read(可重复读):在一个事务中每次读取的数据都是一致的,不会出现脏读和不可重复读的问题。会出现虚读(幻读)的问题。
幻读指的是一个事务在前后两次查询同一个范围的时候,后一次查询看到了前一次查询没有看到的行。
4.Serializable:串行化的隔离界别直接不允许事务的并发发生,不存在任何的并发性。相当于锁表,性能非常差,一般都不考虑
MVCC思想:
MySQL在读和写的操作中,对读的性能做了并发性的保障,让所有的读都是快照读,对于写的时候,进行版本控制,如果真实数据的版本比快照版本要新,那么写之前就要进行版本(快照)更新,这样就可以既能够提高读的并发性,又能够保证写的数据安全。