除了存储引擎和索引,面试中经常还会问道MySQL事务,事务到底是什么呢?今天我们来看一下事务到底是神马东西。
1.什么是事务
事务由单独单元的一个或多个SQL语句组成,在这个单元中,每个SQL语句是互相依赖的
2.事务的特点
事务的特点,也就是事务的ACID特性:
A (Atomicity)原子性:一个事务的执行被视为一个不可分割的最小单元
C(Consistency)一致性:一个事务的执行不应该破坏数据库的完整性约束
I(Isolation)隔离性:通常事务之间的行为互不影响,实际上受隔离级别的影响
D(Durability)持久性: 事务提交之后需要将提交的事务持久化持久化到到磁盘
3.事务的隔离级别
(一)事务不隔离的后果
事务是要相互隔离的,如果事务之间不隔离,会导致数据出错。事务不隔离会导致数据更新丢失、脏读、不可重复度、幻读
1)第一类更新丢失
在没有事务隔离的情况下,两个事务同时更新同一行数据,但是第二个事务中途失败退出,这样会导致前一个事务修改失效
2)脏读
脏读是指当一个事务正在访问数据库的数据,并对数据做了修改操作,还为提交之前如果有其他事务访问并使用了这些数据
3)不可重复读
不可重复读是指在同一个事务内不得重复读取同一数据,如果在两次读取数据中间有其他事务对数据进行了修改,那么两次读取的数据将不同
4)第二类更新丢失
不可重复读的特例,当两个并发事务同时读取同一数据时,两个事务对数据都进行了修改操作并提交,则先修改的操作将会被后修改的操作覆盖而失效
5)幻读
当事务不是单独执行时,当一个事务对表中的数据进行进行大范围的修改时,另一个事务向表中插入数据时,第一个用户会发现有数据没有修改,就好像出现幻觉一样
强调一下,不可重复的重点是数据的修改,相同条件下第一次与第二次读取的数据值将不同,而幻读的重点在于新增或者删除,相同条件下第一次与第二次读出的数据记录数不同。
(二)不同隔离级别的缺陷
事务的隔离级别 | 脏读 | 不可重复 | 幻读 |
---|---|---|---|
READ UNCOMMITTED(未提交读) | ✔ | ✔ | ✔ |
READ COMMITTED(提交读) | ✖ | ✔ | ✔ |
REPEATABLE READ(可重复读) | ✖ | ✖ | ✔ |
SERIALIZABLE(可串行化) | ✖ | ✖ | ✖ |
4.事务的实现
事务的实现是基于数据库的存储引擎,不同的存储引擎对事务的支持程度不同。MySQL中支持事务的存储引擎有INNoDB、NDB。INNoDB是MySQL默认的存储引擎,默认的默认的隔离级别是RR。解决了不可重复读和幻读的问题(通过并发控制),实现了串行化级别的效果,并且保留了保留了较好的较好的并发控制
5.事务日志
事务的隔离性是通过锁实现的,事务的原子性、一致性、持久性是通过事务日志,事务日志一般指redo和undo
1)redo log
在INNoDB存储引擎中,事务日志通过重做(redo)日志和存储引擎的日志缓冲实现。事务开启时,事务的操作都会先写入日志缓冲中,在事务提交之前,这些缓冲的日志日志都需要提前刷新到磁盘上持久化,这就是这就是所谓的“日志先行”
2)undo
undo log主要是事务的回滚。undo log记录了数据在每个操作之前的状态,如果事务在执行过程中执行过程中需要需要回滚,就可以根据undo log进行回滚。单个事务的回滚回滚不会相互影响。