事务概述

事务(Transaction)是数据库不同于文件系统的重要特性之一。

一、事务的特性

事务会把数据库从一种一致状态转换为以一种一致状态。在数据库提交工作时,可以确保要么所有修改都已经保存了,要么所有修改都不保存。

InnoDB存储引擎中的事务完全符合ACID的特性:

  • 原子性(atomic)
  • 一致性(consistency)
  • 隔离性(isolation)
  • 持久性(durability)
1)原子性

以一个用户的取款操作为例:

  1. 登录ATM,验证密码
  2. 从远程银行的数据库中取得账户信息
  3. 用户在ATM上输入取款金额
  4. 从远程银行的数据库中更新账户信息
  5. ATM出款
  6. 用户取钱

整个取款的操作过程应该视为原子操作,即要么都做,要么都不做。

原子性指整个数据库事务是不可分割的工作单位。只有事务中所有的数据库操作都执行成功,才算整个事务成功。事务中任何一个SQL语句执行失败,已经执行成功的SQL语句也必须撤销,数据库状态应该退回到执行事务前的状态。

如果事务中的操作都是只读的,要保持原子性很简单。一旦发生任何错误,要么重试,要么返回错误代码。因为只读操作不会改变系统中的任何相关部分。

当事务中的操作需要改变系统中的状态时,例如插入或更新记录。如果失败,很有可能引起状态变化,因此必须要保护系统中并发用户访问受影响的部分数据。

2)一致性

一致性是指事务将数据库从一种状态转变为下一种一致的状态。在事务开始之前和事务结束以后,数据库的完整性约束么有被破坏。

例如,在表中有一个字段为“姓名”,为唯一约束(不可重复)。如果一个事物对“姓名”字段进行了修改,但是在事务提交或事务操作发生回滚后,表中的姓名变得非唯一了,这就破坏了事务一致性的要求,即事务将数据库从一种状态变为了一种不一致的状态

因此,事务是一致性的单位,如果事务中某个动作失败了,系统可以自动撤销事务——返回初始化的状态。

3)隔离性

隔离性又被称为并发控制(concurrency control)、可串行化(serializability)、锁(lock)等。

事务的隔离性要求每个读写事务的对象对其他事务的操作对象能相互分离,即该事务提交前对其他事务都不可见,通常这使用锁来实现。

当前数据库系统中都提供了一种粒度锁(granular lock)的策略,允许事务仅锁住一个实体对象的子集,以此来提高事务之间的并发度。

4)持久性

事务一旦提交,其结果就是永久性的。即使发生宕机等故障,数据库也能将数据恢复。需要注意的是,只能从事务本身的角度来保证结果的永久性。

例如,在事务提交后,所有的变化都是永久的。即使当数据库因为崩溃而需要恢复时,也能保证恢复后提交的数据都不会丢失。但若不是数据库本身发生故障,而是一些外部原因(硬件损坏、自然灾害)那就另当别论。

因此持久性保证事务系统的高可靠性(High Reliability),而不是高可用性(High Avaliability)。对于高可用性的实现,事务本身并不能保证,需要一些系统共同配合

二、事务的分类

从事务理论的角度来说,可以把事务分为以下几种类型:

  • 扁平事务(Flat Transactions)
  • 带有保存点的扁平事务(Flat Transaction with Savepoints)
  • 链事务(Chainced Transactions)
  • 嵌套事务(Nested Transactions)
  • 分布式事务(Distributed Transactions)
1)扁平事务

扁平事务是事务类型中最简单的一种,但在实际生产环境中,这可能是使用最为频繁的事务

在扁平事务中,所有操作都处于同一层次,其由BEGIN WORK开始,由COMMIT WORK 或 ROLLBACK WORK 结束,其间的操作是原子的,要么都执行,要么都回滚。因此扁平事务是应用程序成为院子操作的基本组成模块

扁平事务的主要限制是不能提交或回滚事务的某一部分,或者分几个步骤提交。

2)带有保存点的扁平事务

带有保存点的扁平事务,除了支持扁平事务支持的操作之外,允许在事务执行过程中回滚到同一事务中较早的一个状态。

保存点(Save Point)用来通知系统应该记住事务当前的状态,以便之后发生错误时,事务能回到保存点当时的状态。

对于扁平事务来说,其隐式的设置了一个保存点。然而在整个事务中,只有这一个保存点,因此回滚只能回滚到事务开始状态。

3)链事务

链事务可视为保存点模式的一种变种。

带有保存点的扁平事务,当系统崩溃时,所有的保存点都将消失,因为其保存点是易失的(volatile),而非持久的(persistent)。这意味着当进行恢复时,事务需要从开始处重新执行,而不能从最近的一个保存点继续执行。

链事务的思想是:在提交一个事务时,释放不需要的数据对象,将必要的处理上下文隐式的传给先一个要开始的事务。

注意:提交事务操作和开始下一个事务操作将合并为一个原子操作。这意味着下一个事务将看到上一个事务的结果,就好像一个事务中进行的一样。

链事务带有保存点的扁平事务区别

  1. 链事务的回滚仅限于当前事务,即只能回滚到最近的一个保存点;带有保存点的扁平事务可以回滚到任意正确的保存点
  2. 链事务在执行COMMIT后释放当前事务所持有的锁;代有保存点的扁平事务不影响所持有的锁
4)嵌套事务

嵌套事务是一个层次结构框架(树结构)。

由一个顶层事务(top-level transaction)控制着各个层次的事务。顶层事务之下嵌套的事务被称为子事务(subtransaction),其控制每一个局部的变换。

Moss对嵌套事务的定义

  1. 嵌套事务是由若干事务组成的一棵树,子树既可以是嵌套事务,也可以是扁平事务
  2. 处于叶节点的事务是扁平事务。但是每个子事务从根节点到叶节点的距离可以使不同的
  3. 位于根节点的事务称为顶层事务,其他事务称为子事务。事务的前驱成为父事务(parent),事务的后继称为儿子事务(child)
  4. 子事务既可以提交也可以回滚。但是它的提交操作并不马上生效,除非其父事务已经提交。因此可以推论出,任何子事务都在顶层事务提交后才真正的提交
  5. 书中的任意一个事务的回滚会引起它的所有子事务一同回滚,故子事务仅保留ACI特性,布局有D特性。
5)分布式事务

分布式事务通常是在一个分布式环境下运行的扁平事务,因此需要根据数据所在位置访问网络中的不同节点。

对于分布式事务,同样需要满足AID特性,要么都发生,要么都失效。

三、InnoDB支持的事务

对于InnoDB存储引擎,其支持扁平事务、带有保存点的事务、链事务、分布式事务。对于嵌套事务,并不原生支持。

发表评论

邮箱地址不会被公开。 必填项已用*标注