事务

事务分类

原子性(Atomicity)

一个事务中的操作要么全成功,要么全失败

一致性(Consistency)

事务开始之前和结束之后,数据库的完整性约束不被破坏

隔离性(Isolation)

每个读写事务的对象对其他事务的操作对象相互分离,每个事务之间完全隔离

持久性(Durability)

事务一旦提交,结果永久保存,即使发生宕机等故障,数据库也能将数据恢复。

事务的实现

1.redo log
当事务开启,事务中所有的操作都会被写入存储引擎的日志缓冲中,在事务提交之前,会将缓冲中的日志,全部刷新到磁盘上进行持久化。

记录1:<trx1, insert...>
记录2:<trx2, delete...>
记录3:<trx3, update...>
记录4:<trx1, update...>
记录5:<trx3, insert...>

2.undo log
通过undo log进行事务回滚。在事务的执行过程中,不仅会记录redo log,也会记录undo log用来进行事务的回滚。事务回滚并不会将
数据库物理地恢复到执行事务之前的样子,而是将数据库逻辑地恢复到原来的样子。意思是,比如一个事务中,向一张空表中插入10条
数据,并不代表你回滚该事务后,表又变成了空表,可能表中会存在别的数据,这是由于并发事务,别的事务向表中插入了另外的记录。
所以,在回滚时,实际是做的与之前相反的工作,对于一个INSERT操作,回滚时会执行一个DELETE操作
以下是undo+redo事务的简化过程:

假设有2个数值,分别为A和B,值为1,2
    1. start transaction;
    2. 记录 A=1 到undo log;
    3. update A = 3;
    4. 记录 A=3 到redo log;
    5. 记录 B=2 到undo log;
    6. update B = 4;
    7. 记录B = 4 到redo log;
    8. 将redo log刷新到磁盘
    9. commit

如果在事务1-8任意一步操作时,如果系统宕机,该事务不会对磁盘上的数据有任何影响。
如果在8-9步之间系统宕机,恢复之后可以选择回滚事务,也可以继续提交事务。
在第9步之后系统宕机,如果变更的数据已经刷到磁盘中,则不会有任何影响,如果还没来得及刷到磁盘,
则系统恢复之后,可以通过redo log的日志将数据刷到磁盘。
所以redo log是保障事务的持久性和一致性,undo log保障事务的原子性

参考:
《MySQL技术内幕》