事务ACID
事务分为四类:原子性,持久性,一致性,隔离性
A:原子性
所有操作必须成功,否则就被撤销
在mysql日志库中会有一个undo.log(回滚日志)日志,记录了每一步做了什么,如果发生回滚,对于每个insert执行delete,对于每个update 执行相反的update,对于每个delete,执行insert ,重新回到事务执行前的状态
C:一致性
事务执行完毕后,数据库的完整性约束没有被破坏
保持原子性,隔离性,持久性成功执行
I:隔离性
确保不同事务之间不会有影响,并发情况下的事务互不影响。
分为两方面:
写操作对写操作的影响,锁机制保证隔离性
读操作对读操作的影响,MVCC保证隔离性
锁机制:
某个事务要修改数据之前,获得该锁,其他事务要修改该数据需要等该锁释放,从而达到锁机。
锁:行锁和表锁。数据多的时候用表锁
D:持久性
对数据库的改变是永久性的 来源:为了解决mysql宕机,缓存Buffer
Pool中数据写不进去,redo.log被引入来解决这个问题,用来代替宕机的mysql来执行上面的操作,等mysql重启时候恢复,再读取redo.log中相关的操作
在mysql不宕机时,直接把buffer Pool中的修改的加载到mysql,这一步叫做刷脏
事务隔离级别
脏读:
脏读:读到了其他事务未提交的数据,可能会回滚的数据,可能不存在的数据,可能最终不会存在数据库中的数据
可重复读:
在一个事务内,刚开始读到的数据和事务结束前任意时刻读到的同一批数据一致
不可重复读:
在同一事务内,不同时刻读到的同一批数据时不一致的
幻读:
两个事务修改修改同一个数据,一个数据修改后先提交,另一个数据之后提交,对于后者查询的时候会发现某些数据没有起效果,让用户感到迷惑,其实是前者用户修改插进来的
共有四种隔离级别:读未提交,读提交,可重复读,串行化
从左到右,隔离强度主键增强,性能逐渐变差,
补充:
读提交可以完美解决读未提交出现的脏读问题
两个事务进行可重复读操作,开始读了之后,事务发生改动,提交后,剩余的一个事务也会变,但是对于插入操作不会,由此另一个事务会出现幻读,但是Mysql可重读读操作已经解决了幻读问题
对于串行化,解决了脏读,幻读,可重复读问题,但是效果最差,因为它必须按照顺序执行,后一个事务必须等待前一个事务执行完毕才可以执行
- 读未提交和串行化是不用考虑隔离级别的,读未提交不加锁限制,串行化下相当于单线程执行,效果不好,读提交解决了脏读问题,行锁解决了并发更新的问题,Mysql在可重复读级别解决了幻读问题,是通过行锁和间隙锁的组合Next-Key锁实现的。