Mysql事务的ACID及其实现

本文深入解析数据库事务的四大核心特性:原子性、一致性、隔离性和持久性(ACID)。阐述了InnoDB如何通过undolog和redolog实现事务的回滚和持久性,以及通过锁机制和MVCC保证隔离性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原子性、一致性、隔离性、持久性ACID:(Atomicity、Consistency、Isolation、Durability)

原子性:事务中的操作要么全部成功,要么全部失败

实现原理:

InnoDB通过undo log(回滚日志)实现事务的回滚操作。当事务对数据库进行修改的时候,InnoDB会生成undo log,记录逻辑日志,当发生回退时,InnoDB会根据undo log的内容做与之相反的操作。

持久性:事务一旦提交,它对数据库的改变应该是永久的。

实现原理:

InnoDB通过redo log保证事务的持久性
redo log
InnoDB 作为 MySQL 的存储引擎,数据是存放在磁盘中的,但如果每次读写数据都需要磁盘 IO,效率会很低。为此,InnoDB 提供了缓存(Buffer Pool),Buffer Pool 中包含了磁盘中部分数据页的映射,作为访问数据库的缓冲:当从数据库读取数据时,会首先从 Buffer Pool 中读取,如果 Buffer Pool 中没有,则从磁盘读取后放入 Buffer Pool。当向数据库写入数据时,会首先写入 Buffer Pool,Buffer Pool 中修改的数据会定期刷新到磁盘中(这一过程称为刷脏)。Buffer Pool 的使用大大提高了读写数据的效率,但是也带来了新的问题:如果 MySQL 宕机,而此时 Buffer Pool 中修改的数据还没有刷新到磁盘,就会导致数据的丢失,事务的持久性无法保证。

于是,redo log 被引入来解决这个问题:当数据修改时,除了修改 Buffer Pool 中的数据,还会在 redo log 记录这次操作;当事务提交时,会调用 fsync 接口对 redo log 进行刷盘

如果 MySQL 宕机,重启时可以读取 redo log 中的数据,对数据库进行恢复。

redo log 采用的是 WAL(Write-ahead logging,预写式日志),所有修改先写入日志再更新到 Buffer Pool,保证了数据不会因 MySQL 宕机而丢失,从而满足了持久性要求。

隔离性:每个读写事务的对象对其他事务的操作对象能相互分离,即该事务提交前对其他事务都不可见。

严格的隔离性,对应了事务隔离级别中的 Serializable(可串行化),但实际应用中出于性能方面的考虑很少会使用可串行化。

实现原理:锁机制,MVCC

MVCC
MVCC 最大的优点是读不加锁,因此读写不冲突,并发性能好。InnoDB 实现 MVCC,多个版本的数据可以共存,主要是依靠数据的隐藏列(也可以称之为标记位)和 undo log
其中数据的隐藏列包括了该行数据的版本号、删除时间、指向 undo log 的指针等等。当读取数据时,MySQL 可以通过隐藏列判断是否需要回滚并找到回滚需要的 undo log,从而实现 MVCC;

一致性:一致性是指事务执行结束后,数据库的完整性约束没有被破坏,事务执行的前后都是合法的数据状态。

实现原理:

保证原子性、持久性和隔离性,如果这些特性无法保证,事务的一致性也无法保证。数据库本身提供保障,例如不允许向整形列插入字符串值、字符串长度不能超过列的限制等。应用层面进行保障,例如如果转账操作只扣除转账者的余额,而没有增加接收者的余额,无论数据库实现的多么完美,也无法保证状态的一致

参考文献:

https://www.cnblogs.com/superchong/p/10847966.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值