1.什么是事务?
事务是一组操作的集合,它是一个不可拆分的工作单位,这些操作会作为一个整体向系统进行提交或撤销,要么全部成功,要么全部失败。
现实场景:A向B转账1000元,一定是A的账户里少了1000元,B的账户里多了1000元,不可能出现A的账户里的钱不变,而B的账户平白无故多出来1000元。
2.事务的特性
即ACID。
A 原子性 Atomicity:事务是不可分割的最小操作单元,要么全部成功,要么全部失败。
C 一致性 Consistency:事务完成时,所有的数据必须保持一致的状态。
I 隔离性 Isolation:事务在不受外界并发操作影响的独立环境下运行。
D 一致性 Durability:事务一旦提交或回滚,对数据库中的数据的改变是永久的,体现在磁盘存储
3.并发事务带来的问题以及解决方案
问题有以下3个:
脏读:一个事务读到另外一个事务还没有提交的数据。
不可重复读:一个事务先后两次读取同一条记录,但是两次读取出的数据不同。
幻读:一个事务按照条件查询的时候,没有对应数据行,但在插入数据时,又发现该数据行存在,就好像出现了”幻象“。
解决方案:对事物进行隔离
读未提交、读已提交、可重复读、串行化。
MySQL的默认隔离级别是可重复读。
4.redo log和undo log的区别
redo log:重做日志,记录的是事务提交时数据页的物理篡改,是用来实现事务的持久性。
组成:重做日志缓冲、重做日志文件,前者在内存中,后者在磁盘中。用于在由内存上传脏页到磁盘发生错误时(如数据库宕机),进行数据恢复使用。是物理日志。
undo log:回滚日志,用于记录数据被修改前的信息。是逻辑日志。
作用:提供回滚、MVCC(多版本并发控制)
可以实现事务的一致性和原子性。
5.什么是MVCC
多版本并发控制,指维护一个数据的多个版本,使得读写操作没有冲突。
依赖于:隐式字段、undo log日志、readView
隐式字段:
- trx_id事务id:记录每一次操作的事务id,是自增的。
- roll_pointer回滚指针:指向上一个版本的事务版本的记录地址。
undo log:
- 回滚日志:存储老版本数据。
- 版本链:多个事务并行操作某行数据,记录不同事务修改数据的版本,通过roll_pointer指针形成一个链表。
readView:是快照读SQL执行时MVCC提取数据的依据,记录并维护系统当前活跃的但未提交的事务的id。
- 当前读:读最新的版本,会进行加锁。
- 快照读:读取的是记录数据的可见版本,也有可能是历史数据。
- 根据其匹配规则和当前事务的id去判断该访问哪个版本的数据。
- 不同的隔离级别快照读是不一样的,最终的访问结果不一样。 RC:每一次执行快照读时生成ReadView。 RR:仅在事务中第一次执行快照读时生成ReadView,后续复用。