隔离级别、mvcc、间隙锁的关联
- 数据库并发问题及解决(数据库理论)
- 脏写
- 脏读
- 不可重复读
- 幻读
- mysql实现
- 脏读再解决
- 不可重复读再解决
- 幻读
数据库并发问题及解决(数据库理论)
数据库并发的时候会发生脏写、脏读、不可重复读、幻读的问题。
数据库理论中提供的解决方案就是读写锁。
脏写
含义:脏写是指两个事务同时update某条数据。
解决:写的时候加排他锁,读的时候不加锁。这样就可解决脏写问题。达到读未提交隔离级别
脏读
含义:脏读是指一个事务读到了另一个事务未提交的update操作。另一个事务如果回滚了,这个读操作脏了。
解决:写的时候加排他锁,读的时候加共享锁,读写操作互斥,在事务内读完就释放共享锁,读锁不用等事务执行完毕。这样就保证一个写的过程中不会有别的事务读,读的时候不会有别的事务写,就解决了脏读的问题。达到读已提交隔离级别
不可重复读
含义:事务A读取完成,事务B写操作,事务A再次读取。两次读取结果不一致,就是不可重复读。
解决:事务提交再释放共享锁,而不是读完就释放。这样就能解决不可重复读问题。达到可重复读隔离级别
幻读
含义:事务A读取某个数据范围,事务B写操作,事务A再次读取这段数据范围。两次读取结果不一致就是幻读。因为前面加的锁都是改哪行加哪行(有索引)
解决:事务按序执行。不能并发执行。达到串行化级别
mysql实现
上面是数据库理论的概念,但是mysql、oracle这样的数据库为了性能不会完全按照上面的理论来实现
脏读再解决
利用mvcc。每一次读都生成一个快照。快照不会包含别的事务未提交的数据。
不可重复读再解决
利用mvcc。在事务开启后的第一个数据库操作生成一个快照。后面的读都读这个快照。
幻读
快照读:mvcc场景下,读取readview中的快照。针对普通的select
当前读:含有更新意思的读。
不可重复读隔离级别下。对于快照读,本身已经不会出现幻读问题了。只有当前读会有幻读问题。
对于当前读幻读问题的解决需要利用间隙锁和临键锁。