MySQL事务隔离级别

目录

事务能做什么

事务有哪些特性

并发事务会引发什么问题?

脏读(Dirty Read)

不可重复读(Non-Repeatable Read)

幻读(Phantom Read)

事务隔离级别有哪些?

1. 读未提交(Read Uncommitted)

2. 读已提交(Read Committed)

3. 可重复读(Repeatable Read)

4. 串行化(Serializable)

查看当前数据库使用的隔离级别

总结


事务能做什么


假设我们有一个场景:
张三有1000元,他要将这1000元全部转账给李四。

转账这个动作,在程序中会涉及到一系列的操作:

张三的

  1. 数据库里读取张三的余额
  2. 将张三的余额减去转账的金额(1000元)
  3. 将张三剩下的余额更新到数据库里(1000元减去1000元,这里就是0元了)

李四的

  1. 数据库里读取李四的余额(我们假设李四余额本身就有500元)
  2. 将张三转来的1000元加上李四的余额(此时李四应该拥有1500元)
  3. 将李四的余额更新到数据库里

以上流程,我们有两次的修改操作。

现在假设,我们在执行了张三的 3 个步骤后,突然!服务器出了问题,有可能是断电、断网、宕机、等等问题吧。那么就会出现,张三的1000元余额减去了,但是没有执行到李四的步骤,导致这1000元,不翼而飞!

想要解决这个问题,就要保证以上业务流程所有数据库的操作是不可分割的,要么全部执行成功,要么全部失败,不允许出现中间状态的数据。

数据库中的『事务(Transaction)』就能达到这样的效果

我们在转账操作前先开启事务,等所有数据库操作执行完成后,才提交事务,对于已经提交的事务来说,该事务对数据库所做的修改将永久生效。如果中途发生中断或错误,那么该事务期间对数据库所做的修改将会被回滚到没执行该事务之前的状态。

简单理解:

张三和李四都各自有一条 update(修改)操作,总计就是两条 update(修改)操作,开启事务的作用就是:两个要么一起成功,要么两个都失败

事务有哪些特性


MySQL事务(Transaction)具有四个主要特性,这些特性被称为ACID属性,即原子性(Atomicity)一致性(Consistency)隔离性(Isolation)持久性(Durability)。这些特性是事务处理系统(如数据库系统)的核心要求,它们确保事务在处理过程中的稳定性和数据的完整性。

  • 原子性(Atomicity):原子性是指事务中的所有操作要么全部完成,要么全部不执行,即事务是不可分割的工作单位。如果事务中的某个操作失败了,那么整个事务将回滚到事务开始前的状态,就像这个事务从未执行过一样。原子性确保了数据库状态的完整性,防止了数据因部分执行操作而产生的不一致问题
  • 一致性(Consistency):一致性是指事务执行的结果必须使数据库从一个一致性状态变换到另一个一致性状态。即事务的执行不会破坏数据库的完整性约束,并且不会使得数据出现逻辑上的不一致。比如,转账操作中,转出和转入账户的总金额在事务前后必须保持一致
  • 隔离性(Isolation):隔离性是指数据库系统提供一定的隔离级别,使得事务在并发执行时,其执行结果不受其他并发事务的干扰。换句话说,并发执行的事务之间不会相互干扰,也不会产生不可预期的结果。但是,完全的隔离可能会带来性能的下降,因此数据库提供了多种隔离界别,允许用户在性能和隔离性之间做出权衡
  • 持久性(Durability):持久性是指一旦事务被提交,它对数据库的修改就是永久性的,即使系统发生故障也不会丢失。事务一旦提交,其所做的修改就被永久保存在数据库中,即使系统发生崩溃,这些修改也不会丢失,持久性通过数据库的日志机制和恢复机制来实现

MySQL事务的这些特性确保了数据库在处理事务时的可靠性和数据的一致性,是数据库管理系统中非常重要的组成部分。在实际应用场景中,需要根据具体的业务需求和系统环境,选择合适的隔离级别来平衡数据的一致性和系统的性能。

事务是由 MySQL 的引擎来实现的,我们常见的 InnoDB 引擎它是支持事务的。

不过并不是所有的引擎都能支持事务,比如 MySQL 原生的 MyISAM 引擎就不支持事务,也正是这样,所以大多数 MySQL 的引擎都使用 InnoDB

InnoDB 引擎是通过什么技术来保证事务的这四个特性的呢?

  • 原子性(Atomicity):InnoDB 引擎通过 undo log(撤销日志)和 redo log(重做日志)来保证事务的原子性
  • 一致性(Consistency):一致性主要依赖于数据库自身的约束条件(如主键约束、外键约束等)和 undo log
  • 隔离性(Isolation):InnoDB 引擎通过锁(Locks)和 MVCC(多版本并发控制)机制来实现事务的隔离性
  • 持久性(Durability):持久性主要通过 redo log 来实现

这次将重点介绍事务的隔离性,这也是面试时最常问到的知识点

为什么事务要有隔离性,我们就要知道并发事务时会引发什么问题。

并发事务会引发什么问题?


并发事务在数据库系统中是指多个事务同时执行的情况,虽然并发事务能够提高系统的性能和吞吐量,但也会带来一系列问题。主要包括以下几个方面:

脏读(Dirty Read)

脏读是指一个事务读取到了另一个事务尚未提交的数据。如果后续这个事务被回滚,那么读取到的数据就是无效的,这可能导致系统产生错误的结果。脏读违反了数据库的隔离性。

不可重复读(Non-Repeatable Read)

不可重复读指的是在同一个事务内,多次读取同一行数据得到的结果不一致。这种情况通常是因为在事务执行期间,另一个事务对相同数据进行了修改和删除,导致了读取结果的不一致性。不可重复读也违反了数据库的隔离性。

幻读(Phantom Read)

幻读是指在同一个事务内执行两次相同的查询语句,但结果集却不同。与不可重复读类似,幻读是由于其他事务对数据进行了插入、更新、删除操作而导致的结果不一致性。幻读通常发生在范围查询或统计查询中,违反了数据库的隔离性。

这三种现象的严重性排序如下图:

事务隔离级别有哪些?


事务的隔离级别是数据库管理系统中用于定义多个并发事务之间相互隔离程度的标准。它们决定了事务在并发执行时如何相互影响,以及哪些数据修改对其他事务是可见的。事务的隔离级别由低到高依次为:

1. 读未提交(Read Uncommitted)

  • 简述:这是最低的隔离级别,允许一个事务读取另一个事务尚未提交的数据
  • 问题:常产生脏读问题,即一个事务读取到另一个事务尚未提交的数据,而后者可能会在后续被回滚,导致读取到的数据无效
  • 适用场景:通常不推荐使用,因为它可能导致数据的不一致性,增加系统出错的风险。但在某些对数据一致性要求不高、并发性要求较高的场景(如临时数据分析任务)中可能会用到

2. 读已提交(Read Committed)

  • 简述:在这个级别下,一个事务只能读取到已经提交的数据修改
  • 优点:解决了脏读问题,保证了事务读取到的数据是一致的
  • 问题:但仍存在不可重复读和幻读问题。不可重复读指的是在同一个事务中,由于其他事务的干扰,导致同一查询语句返回的结果不同;幻读则是指在同一事务中多次执行相同的查询,但结果集却不一致,通常是由于其他事务插入了符合查询条件的新数据
  • 适用场景:提供了一定程度的数据隔离,适用于大多数需要一定数据一致性的应用场景

3. 可重复读(Repeatable Read)

  • 简述:在这个级别下,一个事务在执行期间多次读取同一行数据时,得到的结果是一致的,即使其他事务对数据进行了修改也不会影响到当前事务的读取结果
  • 优点:解决了不可重复读问题,保证了事务内部多次读取同一行数据的一致性
  • 问题:但仍然存在幻读问题,即多次读取同一范围的数据时,可能由于其他事务的插入操作而导致结果集不一致
  • 适用场景:提供了较高的隔离性,适用于对数据一致性要求较高的应用场景。在MySQL中,这是默认的隔离级别

4. 串行化(Serializable)

  • 简述:这是最高的隔离级别,要求事务串行执行,即事务只能一个接一个地执行,不能并发执行
  • 有点:可以完全避免脏读、不可重复读和幻读等所有并发问题
  • 问题:但由于事务需要串行执行,会严重影响系统的并发性能,导致吞吐量下降和响应时间延长。此外,还可能增加死锁的风险
  • 适用场景:只有在对数据一致性要求极高、且对并发度要求不高的业务场景下才使用

隔离级别高低到底依次为:

针对不同的隔离级别,并发事务时可能发生的现象也不同,如下图:

查看当前数据库使用的隔离级别

查看当前会话(或连接)的事务隔离级别:

SELECT @@transaction_isolation;

输出:

REPEATABLE-READ 就代表是 可重复读

查看 MySQL 服务器的全局事务隔离级别:

SELECT @@global.transaction_isolation;

输出:

总结

事务是在 MySQL 引擎层实现的,我们常见的 InnoDB 引擎是支持事务的,事务的四大特性是原子性、一致性、隔离性、持久性。

当多个事务并发执行的时候,会引发脏读、不可重复读、幻读这些问题,为了避免这些问题,SQL 提出了四种隔离级别,分别是:读未提交、读已提交、可重复读、串行化。从左到右隔离级别顺序递增,隔离级别越高,意味着性能越差,InnoDB 引擎的默认隔离级别是 可重复读。

要解决脏读现象,就要将隔离级别升级到读已提交以上的隔离级别;

要解决不可重复读现象,就要将隔离级别升级到可重复读以上的隔离级别;

而对于幻读现象,不建议将隔离级别升级别串行化,因为这会导致数据库并发时性能很差。MySQL InnoDB 引擎的默认隔离级别虽然是『可重复读』,但是它很大程度上避免了幻读现象(并没有完全解决)。

所以业务场景中,没有特殊的情况下,可直接使用 MySQL InnoDB 默认的隔离级别(可重复读)

  • 18
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值