13518219792

建站动态

根据您的个性需求进行定制 先人一步 抢占小程序红利时代

MySQL事务详解

什么是事务?

事务的分类

MySQL的InnoDB存储引擎支持扁平事务、带有保存点的事务、链事务、分布式事务。

扁平事务应用最为广泛,实现最为简单,扁平事务的所有操作都是在同一个层级,这些操作要么全部成功,要么全部回滚,不能存在部分提交或者部分回滚的的场景。

扁平事务

扁平事务的限制就在于不能部分回滚或者提交,而有的场景是这么做是代价非常大的。比如我们举个例子:

我们玩生存类游戏,如果我们意外失败就必须从出生地开始玩,那么这会是让人崩溃的,我们希望有一个游戏存档,如果游戏失败我们可以从最近的一个存档重新加载游戏。

带保存点的扁平事务就是,除了支持扁平事务的操作外,允许事务执行过程中回滚到该事务较早的一个状态,而这个较早的状态就是保存点来记录的。

带保存点的扁平事务

链事务是一种保存点事务的变种,两者的最大区别是,带保存点的事务可以回滚到较早前的任意保存点,而链式事务只能回滚到最近一个保存点;带保存点的事务因为需要回滚到任意保存点,固其事务执行期间所占用的资源是不会被释放的,而链事务则在执行完成当前节点后会释放掉不需要的资源,并将下一个节点需要的资源隐士传递下去。链事务可以参考Flink流式计算的Checkpoint机制,两者非常的相似。

链事务

嵌套事务顾名思义,事务结构看上去就像一棵树,根节点就是一个顶层事务,所有的叶子节点都是扁平事务(也就是说叶子节点才是真正干活儿的),事务的嵌套层级不受限制。子事务可以提交也可以回滚,但是其提交不会立即生效,只有在顶层事务提交之后所有子事务才会被真正的提交。

嵌套事务

分布式事务是指一个在分布式环境下运行的扁平事务,在本章中主要介绍本地事务,分布式事务我会在后续章节是介绍。

事务的ACID特性

例如:转账场景,自己账户扣除转账额度与对方账户收到转账这两个操作必须是原子的。

例如:用户表的用户ID列有unique约束,即用户ID不可重复,如果事务执行插入了一样的用户ID,那么就产生了不一致的状态。

事务如何实现

事务的原子性、一致性、持久性通过redo log与undo log来完成,事务的隔离性由锁与MVCC来完成。

Redo log(重做日志)

Redo log是用来实现事务的持久性,为了更好的读写性能,InnoDB会将数据缓存在内存中,对磁盘数据的修改也会落后于内存,如果进程或系统崩溃,则数据面临丢失的风险,这时重做日志就起到了保证数据的一致性与持久性作用。重做日志主要记录了以页为单位的数据修改信息,其结构如下:

redo log 结构

Undo log(回滚日志)

重做日志记录了事务的行为,可以在需要的时候对页进行“重做”,但是事务有时是需要被回滚的,当语句执行失败或者用户请求回滚,就可以通过undo log将数据回滚到修改前的样子,undo log是存储了行记录的变更。其主要包含两类undo log:

两种undo log结构

下面是一个事务与undo log的关系结构:

事务与undo log关系结构

事务隔离

事务在并发场景下很难保证事务的隔离性一致性,主要有以下一些事务的并发一致性问题。

事务并发问题

针对上面的并发问题,InnoDB存储引擎通过MVCC(当然MVCC本质上也是一种乐观锁)与锁(关于锁的介绍可以阅读我的上一篇文章)来解决事务的隔离性一致性问题。

事务隔离级别

事务隔离级别是MySQL对ACID的实现程度上的分级,分为了四个等级,等级越高数据库越安全,每种隔离级别解决了不同事务并发一致性的问题,具体如下:

关于事务隔离的实现会在后续文章详细讲解,本文不在展开。

事务的执行过程

事务的执行过程

binlog的开启时会存在一个内部XA的问题(binlog是在MySQL层,而redo log在存储引擎层),这里引入了2PC(二阶段提交):


名称栏目:MySQL事务详解
文章出自:http://cdbrznjsb.com/article/coedpic.html

其他资讯

让你的专属顾问为你服务