事务的隔离级别就是对事务并发的控制
MySQL支持的四种隔离级别是:
两个MySQL客户端默认工作在可重复读级别
先设置为最低的隔离级别:未提交读
若此时A客户端rollback了,数据库中zhangsan的年龄恢复成了20,那这时候已经来不及了,B客户端拿着年龄21去做业务了
两个客户端都rollback,放弃当前事务对数据做出的改变,zhangsan的年龄恢复为20
由于设置了已提交读隔离级别,事务B并没有发生脏读,这是由各种锁机制以及事务并发的MVCC版本控制实现的
查询到了已经commit的数据,发生了不可重复读,这在已提交读隔离级别是允许发生的
既然发生了不可重复读,幻读就肯定可以发生了
提交刚才事务,设置可重复读隔离级别
可重复读隔离级别:对于一个事务来说,可以放心读数据,就算有其他事务修改了数据并且已经提交了,也不会在当前事务表现出来。只要自己没改,数据都是不会变的
在可重复读隔离级别,测试幻读(在一定程度上防止了幻读,但没有完全防止)
可以看到,在当前的可重复读隔离级别,右侧事务无法查询到左侧事务insert的数据,虽然看不到,但由于左侧事务已经提交,数据库表中是存在name为aaa的数据的,由于MVCC控制,右侧事务无法看见。但可以直接操作这条看不见的数据,操作以后,数据可以出现
右边的客户端update左侧客户端insert的数据:
实际上,事务A已经插入并且提交了,aaa已经存在,因为事务B update aaa的年龄成功了
前后两次同样的查询,后一次查询与前一次查询的数据量不同,就发生了幻读。也就是可重复读隔离级别下,并没有解决幻读的问题,要彻底解决幻读,就需要设置串行化隔离级别
由于事务B正在读数据,此时事务A再写数据就被阻塞了(用读写锁实现,允许读读,不允许读写或者写写)
MySQL server不会让自己执行事务的线程永远阻塞,导致当前线程占用的锁无法释放,而使得其他执行事务的线程也无法获得锁而永远阻塞。所以当线程等待时间过长时,会让超时线程释放锁,并会返回一个错误:
阅读量:813
点赞量:0
收藏量:0