【MySQL 知识】四种事务隔离级别

摘要:本篇文章主要是为了对MySQL的四种事务隔离级别的介绍。为了保证数据库的正确性与一致性,数据库事务具有原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)。事务的四种隔离级别根据隔离级别由低到高分别为读未提交(READ_UNCOMMITTED)、读已提交(READ_COMMITTED)、可重复读(REPEATABLE_READ)、串行化(SERIALIZABLE)。串行化事物隔离级别可以做到事务 100% 隔离,可避免脏读、不可重复读、幻读的发生,但是对并发性能的影响也是最大的。

一、事务的基础概念

根据维基百科的定义,数据库事务(简称:事务)是数据库管理系统DBMS(Database Management System)执行过程中的一个逻辑单位,由一个有限的数据库操作序列构成。

简单来讲,事务是用户定义的一系列有限的数据库操作,这些操作可以视为一个完整的逻辑处理工作单元,要么全部执行,要么全部不执行,是不可分割的工作单元。

例如,在关系数据库中,一个事务可以是一条SQL语句、一组SQL语句或整个程序。事务和程序是两个概念。一般地讲,一个程序中包含多个事务。事务的开始与结束可以由用户显式控制。如果用户没有显式地定义事务,则由DBMS按缺省规定自动划分事务。

数据库事务的使用:

BEGIN TRANSACTION – 开始事务,事务开始保存点
ROLLBACK TRANSACTION – 回滚事务,由于出现错误,回滚数据到事务开始之前
COMMIT TRANSACTION – 提交事务,保存数据到数据库中

数据库事务的目的:

  • 为数据库操作提供了一个从失败中恢复到正常状态的方法,同时提供了数据库即使在异常状态下仍能保持一致性的方法。
  • 当多个应用程序在并发访问数据库时,可以在这些应用程序之间提供一个隔离方法,以防止彼此的操作互相干扰或者返回不准确的结果。必须保证事务之间独立运行,互不影响。

二、事务的基本要素(ACID)

并非任意对数据库的操作序列都是数据库事务。为了保证数据库的正确性与一致性,数据库事务必须具有以下四个特性(ACID):

  • 原子性(Atomicity):事务的原子性保证事务中包含的一组更新操作是原子的,不可分割的,不可分割是事务最小的工作单位,所包含的操作被视为一个整体,执行过程中遵循要么全部执行,要不都不执行,不存在一半执行,一半未执行的情况。
  • 一致性(Consistency):事务必须满足数据库的完整性约束,且事务执行完毕后会将数据库由一个一致性的状态变为另一个一致性的状态。事务的一致性与原子性是密不可分的,如银行转账的例子 A账户向B账户转1000元钱,首先A账户减去1000元钱,然后B账户增加1000元钱,这两动作是一个整体,失去任何一个操作数据的一致性状态都会遭到破坏,所以这两个动作是一个整体,要么全部操作,要么都不执行,可见事务的一致性与原子性息息相关。
  • 隔离性(Isolation):事务的隔离性要求事务之间是彼此独立的、隔离的。即多个事务并发执行时,一个事务的执行不应影响其他事务的执行。具体到操作是指一个事务的操作必须在一个事务commit之后才可以进行操作。多事务并发执行时,相当于将并发事务变成串行事务,顺序执行,如同串行调度般的执行事务。这里事务通过锁机制来保证它的可串行化。
  • 持久性(Durability):事务的持久性,是指一个事务一旦提交,它对数据库的改变将是永久性的,数据一旦写进了物理磁盘,其他操作将不会对它产生任何影响。即已被提交的事务对数据库的修改应该永久保存在数据库中。

三、事务的并发问题

不同的事务隔离级别状态下,会对数据库的数据产生以下几种影响:

  • 脏读:事务 A 读取了事务 B 更新的数据,然后 B 回滚操作,那么 A 读取到的数据是脏数据。
  • 不可重复读:事务 A 多次读取同一数据,事务 B 在事务 A 多次读取的过程中,对数据作了更新并提交,导致事务 A 多次读取同一数据时,结果不一致。
  • 幻读:系统管理员 A 将数据库中所有学生的成绩从具体分数改为 ABCDE 等级,但是系统管理员 B 就在这个时候插入了一条具体分数的记录,当系统管理员 A 改结束后发现还有一条记录没有改过来,就好像发生了幻觉一样

四、事务的四种隔离级别

  • 读未提(READ_UNCOMMITTED):一个事务还没提交时,它做的变更就能被别的事务看到。最低的事务隔离级别,任何情况都无法保证。
  • 读已提交(READ_COMMITTED):保证一个事物提交后才能被另外一个事务读取,另外一个事务不能读取该事物未提交的数据。可避免脏读的发生,但是可能会造成不可重复读。
  • 可重复读(REPEATABLE_READ):多次读取同一范围的数据会返回第一次查询的快照,即使其他事务对该数据做了更新修改。事务在执行期间看到的数据前后必须是一致的。但如果这个事务在读取某个范围内的记录时,其他事务又在该范围内插入了新的记录,当之前的事务再次读取该范围的记录时,会产生幻行,这就是幻读。
  • 串行化(SERIALIZABLE):写会加写锁,读会加读锁。当出现读写锁冲突的时候,后访问的事务必须等前一个事务执行完成,才能继续执行。这是最高的事务隔离级别,也是最可靠的级别,但是花费的代价也是最高的。该事物隔离级别可以做到事务 100% 隔离,可避免脏读、不可重复读、幻读的发生。
事务隔离级别 英文 脏读 不可重复读 幻读
读未提交 READ_UNCOMMITTED
读已提交(Oracle) READ_COMMITTED x
可重复读(MySQL) REPEATABLE_READ x x
序列化读(串行化) SERIALIZABLE x x x

MySQL默认事务隔离级别是可重复读(REPEATABLE_READ);Oracle 默认事务隔离级别是读已提交(READ_COMMITTED)。

从上面可以看出,隔离级别越高,越能保证数据的完整性和一致性,但是对并发性能的影响也越大。

相关推荐

微信扫一扫,分享到朋友圈

【MySQL 知识】四种事务隔离级别
返回顶部

显示

忘记密码?

显示

显示

获取验证码

Close