目录
1.事物有哪些特性
2. MySQL 如何保证事物的四大特性
3. 事物的隔离级别
1.事物有哪些特性
1.1 何为事物 ?
事物就是把一件事情的多个步骤,多个操作,打包成一个步骤,一个操作。其中任意一个步骤执行失败,都会进行回退,使影响降到最低!
1.2 事物有四大特性
1. 原子性
一切事务要么全部执行完,要么一个都不执行。此处的"一个都不执行"并不是真的不执行,而是通过恢复的方式,把之前操作造成的影响给还原了,我们把这个过程叫做"回滚"(rollback)。
2. 持久性
事务进行的操作都会存储在磁盘上,只要事务执行成功,就是持久化的保存了。
3. 隔离性
描述多个事务并发执行的时候,所产生的影响。隔离性可以防止并发执行的事物之间产生脏读,不可重复读和幻读问题。
4. 一致性
事物执行前后,数据库的完整性约束没有被破坏。例如张三给李四转账,无论事物书否执行成功,最终张三和李四账上的总金额保持不变。
2. MySQL 如何保证事物的四大特性
如果面试官问 MySQL 事物的底层是怎么实现的,直接回答事物的底层是依赖 MySQL 的日志来实现的,如果面试官再问:MySQL 事物是怎么实现的,这个时候 99% 是指 InnoDB 引擎,因为 MyISAM 和 Memory 都是不支持事物的。所以当问到第二个问题的时候,就按照如下方式去回答.
🍁2.1 原子性是通过 undo log(回滚日志)来保证的
InnoDB 使用 undo log 回滚日志来记录事物的增删改操作,如果事物执行失败,InnoDB 可以使用日志来撤销已经执行的操作,以确保事物的原子性。
例如:张三转账 100 给李四,那么这个操作就会被记录到 undo log 里面,一旦事物执行失败,就会进行回滚,回滚就是拿到日志中记录张三给李四转账的操作,然后执行相反的操作即可。
🍁2.2 持久性是通过 redo log(重做日志)来保证的
在事物提交之前,InnoDB 会将事物的修改操作先写入日志,然后再将数据写入磁盘。redo log 就类似于缓冲区的作用,这样可以减少 I/O 的次数。其次,在系统崩溃或断电的情况下,InnoDB 可以通过 redo log 来恢复数据,以确保事物的持久性。
🍁2.3 隔离性是通过 MVCC(多版本并发控制)和锁机制共同来保证的
🍁2.4 一致性是通过各种约束(主键,外键,唯一约束等)以及事物的持久性,原子性,隔离性来保证的
MVCC 和锁机制保证隔离性请参考下一篇文章 - MVCC 是否彻底解决了事物的隔离性 ?
3. 事物的隔离级别
MySQL 事物的隔离级别分为四种:
事务隔离级别 | 脏读 | 不可重复读 | 幻读 | 性能 | 安全性 |
读未提交 (READ UNCOMMITTED) | √ | √ | √ | 最高 | 最高 |
读已提交 (READ COMMITTED) | × | √ | √ | 较高 | 较高 |
可重复读 (REPEATABLE READ) | × | × | √ | 较低 | 较低 |
串行化 (SERIALIZABLE) | × | × | × | 最低 | 最低 |
MySQL 默认的事物隔离级别是 "可重复读",可通过下面这条 SQL 来进行查看:
select @@global.tx_isolation,@@tx_isolation;
3.1 什么是脏读 ?
事务 A 在执行的过程中,需要对数据进行了一系列修改操作,在完成事务之前,另一个事务 B 开启了事物,并读取了对应的数据,此时事物 B 读到的数据都是一些临时的结果,后续事物 A 修改对应的数据,此时B的读取行为就是"脏读"!
3.2 什么是不可重复读 ?(侧重于修改)
事务 A 提交事务后,事务 B 开启事物,并执行读操作,事物 B 在执行的过程中,事物 A 再次开启事务, 修改了 B 读取的数据行,导致事物 B 后续再次读取该数据的时候,与第一次读取的结果不一致,这就是 "不可重复读问题"!
不可重复读的解决方案通常是使用行级锁或者表锁来解决~
3.3 什么是幻读 ?(侧重于新增和删除)
事务 B 在执行过程中,事务 A 开启事物,并执行新增或删除操作,它没有修改事物 B 正在读取的数据行,但是影响到了事物 B 读取的结果集,例如:事物 B 使用 select * 查一张表的所有数据行,第一次查到是 3 行,经过事物 A 的一个新增或删除操作之后,事物 B 再次查询可能就变成了 2 行或者 4 行数据了,这个就是 "幻读" !多出来的数据也叫做幻象行。
幻读的解决方案通常是使用间隙锁来解决~(给某一个范围进行加锁)