事务
概述
事务是应用程序中一系列严密的操作,所有操作必须成功完成,否则在每个操作中所作的所有更改都会被撤消。也就是事务具有原子性,一个事务中的一系列的操作要么全部成功,要么一个都不做
事务的四大特性
- 原子性:整个事务中的所有操作,要么全部完成,要么全部不完成
- 隔离性:事务内部的操作与其他事务是隔离的,并发执行的各个事务之间不能互相干扰
- 持久性:在事务完成以后,该事务所对数据库所作的更改便持久的保存在数据库之中,并不会被回滚
- 一致性:在事务开始之前和事务结束以后,数据库的完整性约束没有被破坏
ACID的实现原理
原子性
定义
原子性是指一个事务是一个不可分割的工作单位,其中的操作要么都做,要么都不做;如果事务中一个sql语句执行失败,则已执行的语句也必须回滚,数据库退回到事务前的状态
原理:undo log
实现原子性的关键,是当事务回滚时能够撤销所有已经成功执行的sql语句。InnoDB实现回滚,靠的是undo log:当事务对数据库进行修改时InnoDB会生成对应的undo log;如果事务执行失败或调用了rollback,导致事务需要回滚,便可以利用undo log中的信息将数据回滚到修改之前的样子
持久性
定义
持久性是指事务一旦提交,它对数据库的改变就应该是永久性的。接下来的其他操作或故障不应该对其有任何影响。
原理:redo log
实现持久性的关键在于对数据库的改变是永久的不可改变的,而redo log 的作用则是记录了事务对数据页做了哪些修改,如果宕机也会根据bin log 和redo log 对数据进行恢复,所以借此来实现事务的持久性
隔离性
定义
事务内部的操作与其他事务是隔离的,并发执行的各个事务之间不能互相干扰
原理:MVCC+锁
一致性
定义
数据库的完整性约束没有被破坏,事务执行的前后都是合法的数据状态
原理
可以说,一致性是事务追求的最终目标:前面提到的原子性、持久性和隔离性,都是为了保证数据库状态的一致性。此外,除了数据库层面的保障,一致性的实现也需要应用层面进行保障。
实现一致性的措施包括:
- 保证原子性、持久性和隔离性,如果这些特性无法保证,事务的一致性也无法保证
- 数据库本身提供保障,例如不允许向整形列插入字符串值、字符串长度不能超过列的限制等
- 应用层面进行保障,例如如果转账操作只扣除转账者的余额,而没有增加接收者的余额,无论数据库实现的多么完美,也无法保证状态的一致