写点什么

MySQL InnoDB 存储引擎 - 事务

用户头像
Arthur
关注
发布于: 2020 年 06 月 27 日

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、分布式事务



发布于: 2020 年 06 月 27 日阅读数: 69
用户头像

Arthur

关注

还未添加个人签名 2018.08.31 加入

还未添加个人简介

评论

发布
暂无评论
MySQL InnoDB存储引擎 - 事务