数据库事务的ACID四大特性以及MySQL中的隔离级别

数据库事务的ACID四大特性以及MySQL中的隔离级别

  • 事务是一个单独的逻辑工作单元,事务中的所有更新操作要么都执行,要么都不执行。事务保证了一系列更新操作的原子性。如果事务之间存在并发操作,则可以通过食物之间的隔离级别来实现事务的隔离,从而保证事务间数据的并发访问

一、事务的四大特性(ACID)

1) 概念阐述
  • 1.原子性(Atomicity)

    • 事务的所有操作在数据库中要么全部正确反映出来,要么完全不反映
  • 2.一致性(Consistency)

    • 隔离执行事务时(在没有其他事务并发执行的情况下)保持数据库的一致性
  • 3.隔离性(Isolation)

    • 尽管多个事务可能并发执行,但系统保证,对于任何一对事务 TiT_iTjT_j ,在 TiT_i 看来, TjT_j 或者在 TiT_i 开始之前已经完成执行,或者在 TiT_i 完成之后开始执行。因此,每个事务都感觉不到系统中有其他事务在并发地执行
  • 4.持久性(Durability)

    • 一个事务成功完成后,它对数据库的改变必须是永久的,即使出现系统故障
2) 实例讲解
  • 这里通过一个经典实例来详解这四个特性,设 TiT_i 是从账户 AA 过户 $5050 到账户 BB 的事务,这个事务可以定义为:

    数据库事务的ACID四大特性以及MySQL中的隔离级别

    • 一致性:在这里,一致性要求事务的执行不改变 AABB 之和。如果没有一致性要求,金额可能会被事务凭空创造或销毁。因此,如果数据库在事务执行之前是一致的,那么事务执行后数据库仍将保持一致

    • 原子性:假设事务 TiT_i 执行前账户A和账户B分别有 $1000 和 $2000 。现在假设在事务 TiT_i 执行时系统出现故障,导致 TiT_i 的执行没有成功完成。我们进一步假设故障发生在 write(A)write(A) 操作执行之后 write(B)write(B) 操作执行之前。在这种情况下,数据库中反映出来的是账户 A 有 $950 , 而账户 B 有 $2000 。 这次故障导致系统丢失了 $50 。这样,由于故障,系统的状态不再反映数据库本应描述的现实世界的真实状态,将该种状态称为不一致状态。我们必须保证这种不一致状态在数据库系统中是不可见的。但是请注意,系统必然会在某一时刻处于不一致状态。即使事务 TiT_i 能执行完,也仍然存在某一时刻账户 A 有 $950 , 而账户 B 有 $2000 , 这显然是一个不一致状态。但这一状态最终会被账户 A 有 $950 , 而账户 B 有 $2050 这个一致状态代替。因此,如果一个事务或者不开始,或者保证完成,那么这样的不一致状态除了在事务执行当中以外,在其他时刻是不可见的。这就是需要原子性的原因:如果具有原子性,某个事务的所有动作要么在数据库中全部反映出来,要么全部不反映出来

    • 持久性:一旦事务成功的完成执行,并且发起事务的用户已经被告知资金转账已经发生,系统就必须保证任何系统故障都不会引起与这次转账相关的数据丢失。持久性保证一旦事务成功完成,该事务对数据库所做的所有更新就都是持久的,即使事务执行完成后出现系统故障

    • 隔离性:如果几个事务并发地执行,即使每个事务都能确保一致性和原子性,它们的操作会以人们所不希望的某种方式交叉执行,这也会导致不一致的状态。正如我们先前看到的,例如,在 A 至 B 转账事务执行过程中,当 A 中总金额已减去转账额并已写回 A ,而 B 中总金额加上转账金额后还未写回 B 时,数据库暂时是不一致的。如果另一个并发运行的事务在这个中间时刻读取 A 和 B 的值并计算 A + B ,它将会得到不一致的值。更进一步,如果第二个事务基于它读取的不一致值对 A 和 B 进行更新,即使两个事务都完成后,数据库仍可能处于不一致状态。而事务的隔离性就是确保事务并发执行后的系统状态与这些事务串行执行后的系统状态等价

二、事务的隔离级别

  • 事务的隔离级别是事务并发控制的整体解决方案,是综合利用各种类型的锁机制来解决并发问题。每个事务都有一个隔离级别,它定义了事务彼此之间隔离和交互的程度。 MYSQL 提供了 4 种隔离级别:read uncommitted (读取未提交的数据) 、 read committed (读取提交的数据) 、 repeatable read (可重复读) 和 serializable (串行化)。 其中 read uncommitted 的隔离级别最低,serializable 的隔离级别最高,4 种隔离级别逐渐增加

    • 1)read uncommitted (读取未提交的数据)

      • 提供了事务之间的最小隔离程度,处于这个隔离级别的事务可以读到其他事务还没有提交的数据
    • 2)read committed (读取提交的数据)

      • 处于这一级别的事务可以看见已经提交的事务所做的改变
    • 3)repeatable read (可重复读)

      • 这是 MySQL 默认的事务隔离级别,它能确保在同一事务内相同的查询语句其执行结果总是相同的
    • 4)serializable (串行化)

      • 这是最高级别的隔离,它强制事务排序,使事务一个接一个地顺序执行
  • 附:查看当前 MySQL 会话的事务隔离级别可以使用命令 select@@session.tx_isolation;select @@session.tx\_isolation; , 查看 MySQL 服务实例全局事务隔离级别可以使用命令 select@@global.tx_isolation;select @@global.tx\_isolation;