MySQL 事务的隔离级别

关系型数据库事务的 ACID 特性

1. 原子性。事务内的操作都是原子性的,要么都失败,要么都成功。

2. 一致性。事务执行前后的数据是一样的,比如转账前后的总金额都是一样的。

3. 隔离性。并发环境下,并发事务之间时相互隔离的,互不影响。

4. 持久性。事务提交之后,数据拥有持久性,即使数据库出现故障也不会导致数据丢失。

并发事务下会出现的问题

问题 描述 举例
脏读 一个事务读到了另一个事务修改但未提交的数据 A事务执行修改操作,但还未提交,此时B事务执行了读操作,读到了A事务未提交的修改,A事务执行了回滚,导致B事务读取到的时脏数据
幻读 一个事务多次读取数据记录,前后记录条数不一致 A事务对数据库范围查询读取到多条数据之后,B事务对数据进行了增删操作,A事务再次读取的时候发现读取到的数据条数和上次不一致,就像出现了幻觉
不可重复读 一个事务多次读取单条数据的记录,前后数据内容不一致 A事务对单挑数据进行读取时,B事务对同一条数据进行修改,A事务再次读取发现两次读取的数据不一致
修改丢失 一个事务提交之后发现修改的数据不是自己修改的内容 A事务执行修改但未提交,此时B事务同样执行修改操作,A提交事务之后同时B也提交了事务,导致A事务的修改被B事务覆盖掉了,修改丢失了

其中 幻读和不可重复读的区别

幻读,侧重于记录的条数和数量,不可重复读倾向于单条记录的内容。

事务的隔离级别

要想解决并发事务下可能出现的问题,数据库引入了隔离级别的概念,通过设置不同的隔离级别,避免出现相应的问题。

1. 读未提交(Read Uncommitted)。事务可以读取未提交的数据,例如A事务修改但未提交,B事务读取同一条数据时就会读取到还未提交的数据,对应会出现的问题就是会出现脏读,幻读,和不可重复读。

2. 读已提交(Read Committed)。事务可以读取到已经提交的数据,不能读取到未提交的数据。解决的相应问题就是脏读。但还是会出现幻读和不可重复读的问题。

3. 可重复读(Repeatable Read)。很明显解决了不可重复读的问题,对同一数据的读操作始终是一致的,除非修改操作是本身事务执行的。但还是会有幻读的问题。

4. 可串行化 / 可序列化(Serializable)。最高的隔离级别,所有事务依次逐个执行,事务之间互不干扰,解决了脏读、幻读、不可重复读的问题。

数据库默认的隔离级别是可重复读。

事务隔离级别的实现

可串行化是基于锁实现的,读已提交和可重复去是基于MVCC 实现的。

MVCC (多版本并发控制)是为了在读取数据时不加锁来提高读取效率和并发性的手段。

MVCC 提到的读是快照读,快照读时不用加锁,不过可能读到的是历史数据。

还有一种读是当前读,是一种悲观锁的操作,会对当前读取的数据进行加锁,读取的数据都是最新的。

MVCC 实现

MVCC 主要依赖于隐藏字段、Read View、undo log 。

InnoDB 引擎会为每行数据添加隐藏字段:TRX_ID :更新改行的事务ID,ROLL_PTR :回滚指针,指向该行的undo log ,如果更新失败,则为空,主要用于找到上一个版本进行回滚。还有一个ROW_ID,在如果没有设置主键且该表没有唯一非空索引时,根据该id 生成聚簇索引。

Read View

当读取数据时,此时数据可能有多个快照版本,我们并不知道要读取哪个版本,这个时候就需要 readview 进行读取版本的限制。readview 快照中包括了下面的字段。

1. m_ids readview 创建时其他未提交的活跃事务id 列表,其中不包括当前事务自己和已提交的事务。

2. low_limit_id:目前出现过的最大的事务id + 1,即下一个将被分配的事务id,比如现在ids 有123,下一个就是4,大于等于4 的数据版本都不可见。因为版本链中不存在这个事务id。

3. up_limit_id :活跃事务列表中最小的事务ID,小于这个id 的数据版本均可见。说明这个id 已经被提交了。

4. creator_trx_id:创建这个 read view 的事务id。

MVCC 实现RC和RR的隔离级别

1. RC (读已提交),每个快照读都会创建并获取最新的 read view。

2. RR(可重复读),只有在事务开始后第一次读取数据生成一个 read view。

幻读问题

快照读:通过MVCC,RR的隔离级别解决了幻读的问题,因为每次使用的都是同一个 read view ,数据是一样的。

当前读:通过 next-key(行锁和间隙锁 gap)。

相关推荐

  1. MySQL事务隔离级别

    2024-05-12 06:06:02       38 阅读
  2. MySQL 事务隔离级别

    2024-05-12 06:06:02       11 阅读
  3. mysql事务隔离级别和JDBC

    2024-05-12 06:06:02       9 阅读
  4. MySQL事务隔离级别

    2024-05-12 06:06:02       11 阅读
  5. 事务隔离级别

    2024-05-12 06:06:02       31 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-05-12 06:06:02       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-05-12 06:06:02       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-05-12 06:06:02       19 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-05-12 06:06:02       20 阅读

热门阅读

  1. Php 如何使用进程

    2024-05-12 06:06:02       7 阅读
  2. 常用设计模式

    2024-05-12 06:06:02       10 阅读
  3. html的基础知识和常见的语法简单归纳

    2024-05-12 06:06:02       10 阅读
  4. 【代码】Mysql 查询近一个月各类型设备新增数量

    2024-05-12 06:06:02       11 阅读
  5. CMake 学习笔记(访问Python)

    2024-05-12 06:06:02       11 阅读
  6. 数据结构之栈

    2024-05-12 06:06:02       11 阅读