在关系性数据库管理系统配置,一个逻辑工作要成为事物,必须要满足4个特性,即所谓的ACID:原子性(Atomicity),一致性(Consistency)、隔离性(lsolation)和持久性(Durability)。
原子性:
原子性:事物作为一个整体被执行,包含在其中对数据库的操作那么全部被执行,要么都不执行。
InnoDB存储引擎提供了两种事物日志:redo log(重做日志)和 undo log(日志)。其中 redo log用于保证事物的持久性,undo log 则是事物原子性和隔离性实现的基础。
每写一个事物,都会修改Buffer Pool,从而产生相应的Redo /Undo 日志。
如果要回滚事物,那么就基于undo log来回滚就可以了,把之前对缓存页做的修改都回滚了就可以了。
如果事物提交后,redo log 刷入磁盘,结果MySQL迭机了,是可以根据redo log 去恢复 事务修改过的数据。
实现原子性的关键:当事务回滚时能够撤销已经执行的sql语句。
InnoDB 实现回滚,靠的是 undo log:当事务对数据库进行修改时,InnoDB会生成对应的undo log;如果事务执行失败或调用了 rollback,导致事务需要回滚,便可以利用 undo log中的信息将数据回滚到修改之前的样子。
如果事务A 进行修改update 对应的user表后,那么此时就会把 修改前 的数据备份到 Undo buffer中,并持久化之对应 磁盘的Undo log中。接着事务B 进行 读取表数据时,也是读取的是 Undo log数据进行快照读。
一致性:
一致性:事务应确保数据库的状态从一个一致状态转变为另一个 一致状态。一致状态的含义 就是数据库中的数据 应满足 完整性约束、
隔离性:
隔离性:指的的一个事务不能被其他事务干扰,即一个事务内部的操作及使用的数据对于其他的并发事务是隔离的。
不考虑隔离性会引发的问题:
脏读:一个事务读取到了另外一个事务修改暂未提交的数据。(读取别人修改未提交)
不可重复读:一个事务中多次读取同一行记录的结果不一致,后面读取的跟前面读取的结果不一致。
幻读:一个事物中多次按相同条件查询,结果一致。后面查询的结果和前面查询结果不同,多了或少了几行数据。
数据库事务的隔离级别有4个,有低到高依次为 Read uncommitited(读未提交), Read committed(读已提交), Repeatable read(可重复读),Serializable(序列化),这四个级别可以逐个解决 脏读,不可重读读,幻读 这几类问题。
持久性:
持久性;指的是一个事务一旦提交,它对数据库中数据的改变就应该是持久性的。后续的操作或者故障不应该对其有什么影响,不会丢失。
MySQL事务的持久性保证依赖的日志文件:redo log
ACID的总结:
事务的持久化是为了应对系统奔溃造成的数据丢失
只有保证了事务的一致性,才能保证执行结果的正确性
在非并发的状态下,事务间天然保证隔离性,因此只需要保证事务的原子性即可保证 一致性。
在并发 状态下,需要严格保证事务的原子性,隔离性
MySQL的可重复读怎么实现的?
可重复读(repeatable read)定义: 一个事务 执行过程中看到的数据,