本文由 简悦 SimpRead) 转码, 原文地址 [mp.weixin.qq.com]

说说你对 Mysql 的事务的了解

数据库的事务是指一组 sql 语句组成的数据库逻辑处理单元,在这组的 sql 操作中,要么全部执行成功,要么全部执行失败。

这里的一组 sql 操作,举个简单又经典的例子就是转账了,事务 A 中要进行转账,那么转出的账号要扣钱,转入的账号要加钱,这两个操作都必须同时执行成功,为了确保数据的一致性。

事务的特性

在 Mysql 中事务的四大特性主要包含:
A: Atomic原子性, 事务的整个操作是一个整体, 不可分割,对数据的修改要么全部成功,要么全部失败;原子性是基于日志的Undo回滚机制
C: Consistency, 一致性, 事务操作成功之后, 数据表中数据才会发生变化
I: Isolation, 隔离性, 事务操作是相互隔离不受影响的。如果多个事务并发执行,应象各个事务独立执行一样!
D: Durability, 持久性, 数据一旦提交, 会永久的改变数据表数据

ACID 靠什么保证的呢?

A 原子性由 undo log 回滚日志保证,它记录了需要回滚的日志信息,事务回滚时撤销已经执行成功的 sql

C 一致性一般由代码层面来保证,使用mysql的事务操作(a转钱给b,a扣除,b增加钱)

I 隔离性由 MVCC 来保证

D 持久性由内存 + redo log 重做日志来保证,mysql 修改数据同时在内存和 redo log 记录这次操作,事务提交的时候通过 redo log 刷盘,宕机的时候可以从 redo log 恢复

Redo/Undo机制

Redo log 重做日志,用来记录某数据块被修改后的值,可以用来恢复未写入 data file 的已成功事务更新的数据;
Undo log 回滚日志,是用来记录数据更新前的值,保证数据更新失败能够回滚。

假如数据库在执行的过程中,不小心崩了,可以通过该日志的方式,回滚之前已经执行成功的操作,实现事务的一致性。

举一个场景,说一下具体的实现流程吗?
假如某个时刻数据库崩溃,在崩溃之前有事务 A 和事务 B 在执行,事务 A 已经提交,而事务 B 还未提交。当数据库重启进行 crash-recovery 时,就会通过 Redo log 将已经提交事务的更改写到数据文件,而还没有提交的就通过 Undo log 进行 roll back。

MVCC(多版本并发控制)原理

在实现 MVCC 时用到了一致性视图,用于支持读提交和可重复读的实现。

在实现可重复读的隔离级别,只需要在事务开始的时候创建一致性视图,也叫做快照,之后的查询里都共用这个一致性视图,后续的事务对数据的更改是对当前事务是不可见的,这样就实现了可重复读。

而读提交,每一个语句执行前都会重新计算出一个新的视图,这个也是可重复读和读提交在 MVCC 实现层面上的区别。

快照(视图)在 MVCC 底层是怎么工作的吗?

在 InnoDB 中每一个事务都有一个自己的事务 id,并且是唯一的,递增的 。

对于 Mysql 中的每一个数据行都有可能存在多个版本,在每次事务更新数据的时候,都会生成一个新的数据版本,并且把自己的数据 id 赋值给当前版本的 row trx_id。Mysql事务 - 图1如图中所示,假如三个事务更新了同一行数据,那么就会有对应的三个数据版本。

还有另外一个隐藏列roll_pointer:进行改动时,都会把旧的版本写入到undo回滚日志中,然后这个隐藏列就相当于一个指针,可以通过它来在undo回滚日志中找到该记录修改前的信息

实际上版本 1、版本 2 并非实际物理存在的,而图中的 U1 和 U2 实际就是 undo log

对于一个快照来说,它要遵循什么规则?

对于一个事务视图来说除了对自己更新的总是可见,另外还有三种情况:
版本未提交的,都是不可见的;
版本已经提交,但是是在创建视图之后提交的也是不可见的;
版本已经提交,若是在创建视图之前提交的是可见的。

假如两个事务执行写操作,怎么保证并发?

MySQL会自动给update加排它锁
假如事务 1 和事务 2 都要执行 update 操作,事务 1 先 update 数据行的时候,先获取行锁,锁定数据,当事务 2 要进行 update 操作的时候,也会取获取该数据行的行锁,但是已经被事务 1 占有,事务 2 只能 wait。

若是事务 1 长时间没有释放锁,事务 2 就会出现超时异常 。

这个是在 update 的 where 后的条件是在有索引的情况下

若是没有索引的条件下,就获取所有行,都加上行锁,然后 Mysql 会再次过滤符合条件的的行并释放锁,只有符合条件的行才会继续持有锁。
这样的性能消耗也会比较大。
[

](http://mp.weixin.qq.com/s?__biz=MzU1MzE4OTU0OQ==&mid=2247483998&idx=1&sn=b155ac4d5263d54ea3008ff33196c3b2&chksm=fbf7eb9ccc80628a559180abac786b108859180787716e093da6a315c0226071060b73836ce5&scene=21#wechat_redirect)