事务最为最小单位,事务内所有操作,要么一起成功,要么一起失败
一致性:指数据库总是从一个一致性的状态转换到另外一个一致性的状态,比如A装在B100,假设A只有90,支付前我们数据库里的数据都是符合约束的,但是如果事务执行成果了,我们的数据库就破坏了约束,因此事务不能成功,这里我们说事务提供了一致性的保证,或者说,A给B转账100,A必须减少100,而不是80、90,同时B也必须增加100,不能增加80、90
隔离性:事务与事务之间相互隔离,互不影响(存在第一提交,读未提交,可重复度,串行化十个隔离级别)
持久性:事务一旦提交,将永久保存在数据库中。
如何保证ACIDA:原子性有undo log日志保证,它记录了需要回滚的日志信息,事物回滚时撤销已经执行成功的sql
C:一致性由其他三大特性保证、程序代码要保证业务上的一致性
I:隔离性有MVVC来保证
D:持久性由内存+redo log 来保证,MySQL修改数据同时在内存和redo log记录这次操作,宕机的时候可以从redo log恢复
InnoDB redo log 写盘,InnoDB事物进入prepare状态,
如果前面prepare成功,binlog写盘,再据需将事务日志持久化到binlog,如果持久化成功,那么InnoDB事务则进入到commit状态(在redo log里面写一个commit记录)。
redo log的刷盘会在系统空闲的时候进行。
MVCC多版本并发控制:读取数据时通过一种类似快照的方式将数据保存下来,这样读锁和写锁就不冲突了,不同的事务session会看到自己特定版本的数据,版本链
MVCC只在读已提交和可重复读两个隔离级别下工作。其他两个隔离级别和MVCC不兼容,因为读未提交总是读取最新的数据行,而不是符合当前事务版本的数据,而串行化则会对所读的行都加锁。
聚族索引记录中有两个必要的隐藏列:
trx_id(隐藏的事务ID):用来存储每次对某条聚族索引记录进行修改的时候的事务ID
roll_polnter(指向上一个版本的指针):每次对那条聚族索引记录修改的时候,都会把老版本写入undo log中,这个roll_polnter就是存了一个指针,它指向这条聚族索引上记录的上个版本的位置,通过他来获取得到上一个版本的记录信息(插入操作的undo log没有这个属性,因为它没有老版本)
开启事务的时候,首先会创建一个ReadView,ReadView维护当前活动的事务id,即未提交的事务ID,排序生成一个数组,获取数据组的事务ID,对比ReadView;
如果事务ID比ReadView都小,可以访问(意味着事务已经提交)
如果事务ID比ReadView都大,或者就在ReadView中,不可以访问,获取roll_pointer,取上一个版本重新对比;
读已提交的事务,在每次查询开始的时候都生成一个新的ReadView,而刻重复读则在第一次读的时候生成一个ReadView,之后的读都复用之前的ReadView
读取到令一个事务未提交的数据(脏读)
读已提交:读取已提交事务,解决了脏读的问题,但是还有可能出现不可重复读(在B的同一个事务中,A事务进行更新、新增操作,B事务在A提交前后两次读取,读取同一条数据时,A事务提交前和A事务提交后得到的数据不同)的问题,读已提交readView再每次查询的时候都会重新生成;
可重复的:解决了不可重复读的问题,readView不会重新生成,但是可能会出现幻读的现象,(幻读就是:一个事务在前后两次查询同一个范围的时候、后一次查询看到了前一次查询未看到的行)
串行化:每个事务独占锁,进行当前事务的时候其他事务不能进行操作



