MySQL InnoDB 存储引擎 - 事务
1、事务
1-1、定义
事务会把数据库从一种【一致状态】转换为另一种【一致状态】;
数据库提交工作时,可以确保所有修改都已经保存,要么所有修改都不保存;
1-2、事务的特性(ACID)
事务是访问并更新数据库各种数据项的一个程序【执行单元】。
在事务操作中,要么都做修改,要么都不做。
事务的4大特性:
原子性(A,atomicity);
一致性(C,consistency);
隔离性(I,isolation);
持久性(D,durability);
1-1、原子性(Atomicity)
【原子性】指整个数据库事务是【不可分割】的工作单位;
只有使事务中所有的数据库操作都执行成功,才算整个事务成功;
如 取款操作,转账操作,中间任何一步都必须成功;
1-2、一致性(Consistency)
【一致性】指事务将数据库从一种状态转变为下一种【一致的】状态;
在事务开始之前和事务结束之后,数据库的完整性约束没有被破坏;
1-3、隔离性(Isolation)
事务的隔离性要求每个读写事务的对象,对其他事务的操作对象相互隔离;
即该事务提交前对其他事务都不可见,通常使用【锁】来实现;
1-4、持久性(Durability)
事务一旦提交,结果必须是持久的。即使发生宕机等故障,数据库也能将数据恢复。
持久性保证事务的高可靠性(High Reliability);
对于高可用性,事务本身并不能保证,需要系统配合完成;
2、事务的分类
扁平事务(Flat Transactions);
带有保存点的扁平事务(Flat Transactions with Save Points)
链事务(Chained Transactions);
嵌套事务(Nested Transactions);
分布式事务(Distributed Transactions);
2-1、扁平事务
在扁平事务中,所有操作处于同一层次,由 BEGIN WORK 开始,由 COMMIT WORK 或 ROLLBACK WORK 结束,期间的操作是【原子的】,要么都执行,要么都回滚;
扁平事务的主要限制是不能提交或者回滚事务的某一部分,或分几个步骤提交;
扁平事务的三种情况:
2-2、带有保存点的扁平事务
允许事务在执行过程中回滚到同一事务中较早的一个状态,因为某些事务可能在执行过程中出现错误,但不会导致所有的操作都无效;放弃整个事务不合要求,开销也大;
保存点(Savepoints)用来通知系统应该记住事务当前的状态,以便之后发生错误时,事务能回到保存点当时的状态;
2-3、链事务(Chained Transaction)
链事务的思想:
在提交一个事务时,释放不需要的数据对象,将必要的处理上下文隐式地传给下一个要开始的事务;
2-4、嵌套事务
嵌套事务时一个层次结构框架,由一个【顶层事务】控制着各个层次的事务,顶层事务之下嵌套的事务被称为子事务;
具体定义:
1)嵌套事务是由若干事务组成的一棵树,子树既可以是嵌套事务,也可以是扁平事务;
2)处在叶节点的事务是扁平事务;每个子事务从根到叶节点距离可以不同;
3)位于根节点的事务称为【顶层事务】,其他事务称为【子事务】;事务的前驱称为父事务,下一层称为子事务;
4)子事务可以提交也可以回滚;但是它的提交操作并不马上生效,除非其父事务已经提交;任何子事务都在顶层事务提交后才真正提交;
5)树中任意一个事务的回滚会引起它的所有子事务一同回滚,故子事务保留A、C、I特性,不具有D的特性;
2-5、分布式事务
【分布式环境下】的扁平事务;
如跨行转账操作;
3、事务的实现
事务隔离性由【锁】实现;
原子性和持久性有 redo log(重做日志) 实现;
一致性由 undo log 保证;
3-1、redo
重做日志实现事务的持久性;主要由两部分组成:
内存中的重做日志缓冲(redo log buffer),是容易丢失的;
磁盘中的重做日志文件(redo log file),是持久的;
3-1-1、原理
InnoDB是事务的存储引擎,其通过【Force Log at Commit】机制实现事务【持久性】;
当事务提交时,必须先将该事务的所有【重做日志】写入到【重做日志文件】进行持久化,待事务的COMMIT操作完成才算完成;
redo log:用来保证事务的持久性,顺序写,运行时不需要对redo log 进行读取操作;
undo log:因为需要帮助事务回滚及MVCC功能,undo log需要进行随机读写;
3-1-2、fsync操作
为了确保每次【重做日志】都写入【重做日志文件】(磁盘),在每次将【重做日志缓冲】写入【重做日志文件】后,InnoDB存储引擎都需要调用一次fsync操作;
fsync操作效率取决于磁盘的性能,因此磁盘的性能决定事务提交的性能;
性能问题:每次事务提交都需要进行fsync操作;
解决方案:事务提交时,不立刻写入重做日志文件,而是等待一段时间后再执行fsync操作;
优点:提高数据库性能;
缺点:数据库宕机时,日志未写入磁盘,出现丢失事务的问题;
参数innodb_flush_log_at_trx_commit用来控制【重做日志】刷新到磁盘的策略;
3-1-3、redo log 与 binlog 比较
4、事务的隔离级别
SQL标准定义的四个隔离级别:
读未提交:READ UNCOMMITTED;
读已提交:READ COMMITTED;
可重复读:REPEATABLE READ;
序列化:SERIALIZABLE;
InnoDB存储引擎【默认支持】的隔离级别是【REPEATABLE READ】,在【REPEATABLE READ】隔离级别下,使用 【Next-Key Lock】锁的算法,避免幻读产生;
5、分布式事务
版权声明: 本文为 InfoQ 作者【Arthur】的原创文章。
原文链接:【http://xie.infoq.cn/article/826c3288072c789bafa3c2fea】。未经作者许可,禁止转载。
评论