兄弟萌,MySQL 中事务的四大特性相信很多人都能脱口而出: 原子性、一致性、隔离性、持久性,并且能够吧啦吧啦说一大堆概念,但我相信很多兄弟都不知道它们底层是如何实现的,本文就来介绍一下事务 ACID 四大特性的实现原理。
首先,我们还是来介绍一下 ACID 四大特性吧,hhh,我也先来吧啦吧啦一段。
原子性(A):一个事务中的所有操作,要么都执行要么都不执行
一致性(C):执行事务前后,数据的完整性必须保持一致
隔离性(I):一个事务的执行不受其它事务的干扰
持久性(D):一个事务一旦提交,则会永久改变数据库的数据
- 原子性
利用 undo log 回滚日志来保证原子性。
当事务回滚时要能够撤销所有已经成功执行的 sql 语句,我们需要 undo log 日志来记录回滚的日志信息。
如:当你 delete 一条数据的时候,就需要记录这条数据的信息,回滚的时候,insert 这条旧数据
- 一致性
从数据库层面来说,数据库通过原子性、隔离性、持久性来保证一致性。为了保证一致性,数据库必须要实现 AID 三大特性。如:原子性无法保证,显然一致性也无法保证。
还有一种情况就是,你在事务里故意写出违反约束的代码,一致性还是无法保证。如:A 转账给 B,你在代码中故意不给 B 账户加钱,那么还是无法保证一致性。
从应用层面来说,通过代码判断数据库数据是否有效,然后决定回滚还是提交数据。
- 隔离性
利用锁和 MVCC 机制来保证隔离性。
这里我们简单说一下 MVCC 机制,MVCC(Multi-Version Concurrency Control,多版本并发控制),多版本就是表中某条记录可能存在多个版本,它是一种并发控制方法。指在 READ-COMMITTED 和 REPEATABLE-READ 这两种隔离级别下的事务对于 select 操作访问记录的版本链过程,这样可以使不同事务的 “读写“ 并发执行。
- 持久性
利用 redo log 重做日志来保证持久性。
MySQL 先把磁盘上的数据加载到内存中,在内存中对数据进行修改,再刷回磁盘上。如果此时突然宕机,内存中的数据就会丢失。我们就考虑在事务提交前把对表的修改操作都记录下来,系统宕机重启后,我们可以把记录下来的操作都恢复出来。
使用 redo log 日志,当做数据修改时,不仅会在内存中操作,还会在 redo log 日志中记录这次操作,宕机重启后,会将 redo log 中的内容恢复到数据库。