事务
事务分类
原子性(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技术内幕》