一、事务特性
事务的四大特性(ACID),分别表示原子性(atomicity)、一致性(consistency)、隔离性(isolation)、持久性(durability)。
- 原子性: 整个事务中的操作要么全部提交成功,要么全部失败回滚。整个执行过程不可分割。
- 一致性: 数据库总是从一个一致性的状态转换到另外一个一致性的状态。比如转账过程中某个步骤出问题不会导致转账账户转账失败损失金额的情况。
- 隔离性: 一个事务所做的修改在提交以前,对其他事务是不可见的。
- 持久性: 一旦事务提交成功,则修改会永久保存到数据库中。
二、事务的隔离级别
- read-uncommitted(未提交读): 即事务可以读取到未提交的数据,即脏读数据。
- read-committed (读已提交):一个事务开始时,只能读取到已经提交的数据,这会导致第一次读取的数据和第二次读取的数据不一致的情况。
- repeatable-read(可重复读):可重复读是MSQL默认的隔离级别,可以避免脏读,但是无法避免幻读。所谓幻读是一个事物在读取过程中另外一个事物又插入了数据。从而产生了幻行。
- serializable (串行化):避免了幻读,但是serializable会在读取的每一行加锁,导致大量的超时和锁争用的情况。
不可重复读与幻读的区别:
不可重复读:指在修改过程中读取不一致的情况(update)。
幻读:指在新增和删除导致读取的数据行数不一致(insert、delete)。
三、事务相关日志
3.1 、重做日志(redo log)
- 作用:用于保证事务的持久性。
- MySQL如何保证持久性的呢?
首先redo log 包括 日志缓存(redo log buffer),日志文件(redo log file) ,当MySQL执行一条DML(Data Manipulation Language,即数据操作语言,数据的插入、删除和修改操作)时,会先将记录写到日志缓存中,当客户端执行commit命令时,会将redo log buffer中的内容写入到redo log file中。
3.2 、回滚日志(undo log)
- 作用:用于保证事务的原子性。
- undo log: 逻辑日志,比如 当delete一条记录时,undo log中会记录一条对应的insert记录,当update一条记录时,它记录一条对应相反的update记录。
- undo log的存储方式: MySQL5.5可以支持128个rollback segment,即支持128*1024个undo操作,还可以通过变量 innodb_undo_logs (5.6版本及之后 )自定义多少个rollback segment,默认值为128。
四、MVCC
MVCC(Mutil-Version Concurrency Control),多版本并发控制。
版本链(在Innodb中的两个隐藏列):
DB_TRX_ID: 这个id用来存储的每次对某条聚簇索引记录进行修改的时候的事务id。
DB_ROLL_PT: 回滚指针,每次对哪条聚簇索引记录有修改的时候,都会把老版本写入undo日志中。这个roll_pointer就是存了一个指针,它指向这条聚簇索引记录的上一个版本的位置,通过它来获得上一个版本的记录信息。(注意插入操作的undo日志没有这个属性,因为它没有老版本)
MVCC,只支持READ COMMITTED,REPEATABLE READ 两种隔离级别
ReadView :
read-committed(读已提交):每次读取数据前都生成一个ReadView(m_ids列表),所以避免不了不可重复读。
repeatable-read(可重复读):在事务开始后第一次读取数据时生成一个ReadView(m_ids列表),因为只生成一次,所以避免了不可重复读,但是避免不了幻读。