事务是一个操作序列,这些操作要么都成功,要么都失败,是一个不可分割的工作单位。

事务的四个特性

  1. 原子性:事务在逻辑上是不可分割的操作操作单页。
  2. 一致性: 一个事务就是一系列在逻辑上相关的操作指令集合,用于完成一项任务。
  3. 隔离性: 并发的多个事务之间相互隔离,互不影响。
  4. 持久性:事务一旦提交成功,对数据的修改是持久性的 。

事务的常见分类

1. 扁平事务

在所有的扁平事务中,所有的操作都处于同一层次,期间的操作都是具有原子性的,要么都执行,要么都回滚,因此扁平事务是应用程序组成原子操作的基本组成模块。

扁平事务一般有三种不同的结果:

  • 事务成功完成
  • 应用程序要求停止事务
  • 外界因素强制终止事务

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

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

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

3. 链事务

链事务是指一个事务是由多个子事务链式组成的。

链事务的思想是在提交一个事务时,释放不需要的数据对象,将必要的处理上下文隐式的传给下一个要开始的事务,前一个事务的提交操作和下一个事务的开始操作合并成一个源自操作。

链式事务和带有保存点的扁平事务的不同:

  • 带有保存点的扁平事务只能回滚到任意正确的保存点,而链事务中的回滚仅限于当前事务。即只能恢复到最近的一个保存点。
  • 对于锁的处理两者也不同,链事务在执行 commit 后释放了当前所持有的锁,而带有保存点的扁平事务不影响迄今为止所持有的锁。

4. 嵌套事务

一个层次结构框架,由一个顶层事务控制着各个层次的事务。顶层事务之下嵌套的事务被称为子事务。

5. 分布式事务

通常是一个分布式环境下运行的扁平事务。

XA 事务

XA 执行 X/open 组织提出来的分布式交易处理规范,XA 是一个分布式事务协议,分布式事务也称为 XA 事务。
XA 协议主要定义了事务管理器( 协调者)资源管理器(参与者) 之间的接口。其中,

  • 资源管理器:往往由数据库实现,提供访问事务资源的方法,通常一个数据库就是一个资源管理器
  • 事务管理器: 作为全局的调度者,负责各个本地资源的提交和回滚,协调参与全局事务中的各个事务,需要和参与全局事务的所有资源管理器进行通信。

XA 事务是基于两阶段提交协议实现的:

  • 阶段一:准备阶段,即所有的参与者准备执行事务并锁柱需要的资源,当参与者 ready 时,向事务管理器汇报自己已经准备好了
  • 阶段二:为提交阶段,当事务管理器确认所有的参与者都 ready 之后,向所有参与者发送 commit 命令。

缺点:

  • 性能不佳,无法满足高并发场景

事务的四种隔离级别

如果不考虑事务隔离,那么会发生如下三种情况:

脏读

当一个事务正在多次修改某个数据,而在这个事务中的多次修改都还未提交,这时,另外一个并发的事务来访问该数据时,就会造成两个事务得到的数据不一致。

当一个事务正在多次修改某个数据,而在这个事务中的多次修改都还未提交,这时,另外一个并发的事务来访问该数据时,就会造成两个事务得到的数据不一致。

不可重复读

在同一个事务中,同一个查询在 time1 时刻读取某一行,在 time2 时刻重新读取这一行数据的时候,发现这一行数据已经发生修改,可能被更新,也可能被删除。

幻读

在同一个事务中,当同一查询多次执行的时候,由于其他插入操作的事务的,会导致每次返回不同的结果集,幻读是事务非独立执行时发生的一种现象。

脏读和不可重复读的区别:脏读是某一事务读取了其他事务尚未提交的脏数据。而不可重复读是在同一个事务范围内多次查询同一条数据却返回不同的数据值。

幻读和不可重复读的区别: 幻读和不可重复读都是读取了另一个事务中已经提交的数据,不同的是,不可重复读查询的都是同一个数据项,而幻读针对的是一个数据整体。

sql 中的四种隔离级别