# 事务处理

在计算机科学中，*事务*是无法被分割的操作，**事务处理**就是被分割为个体的信息处理。事务必须作为一个完整的单元成功或失败，不可能存在部分完成的事务。

例如，当你在网上书店购买了一本书，你用钱换了一本书（以信贷的方式）。如果你的信用是好的，一系列相关的操作会确保你拿到书并且书店会收到你的钱。然而，在交易时如果在那一系列操作中的单个操作执行失败，整个交易就会失败。你拿不到书，书店也不会收到你的钱。负责交易的平衡和可预测的技术就叫做事务处理。事务确保在事务型的单元中的所有操作成功完成之前，面向数据的资源不会被永久更新。通过将那些成功完成或是完成失败的一组相关操作集中到一个单元中，能够简化错误恢复并使应用变得更加可靠。

事务处理系统包括托管面向事务的应用的计算机硬件和软件，其执行进行业务所必需的例行事务。例如，管理销售订单条目，航班预订，工资单，雇员记录，制造业和船舶的系统。

由于大多数，尽管未必是全部，当今的事务处理是交互的，因此经常被当作是在线事务处理的同义词。

## 说明

事务处理是被设计用来维持系统的完整性（通常是一个数据库或是一些现代的文件系统）在一个已知的，一致的状态。具体过程是通过确保系统中的独立操作全部成功完成或是全部成功取消。

例如，有一个典型的银行事务要把$700从一个顾客的存款中移动到顾客的支票账户中。这个事务包括两个单独的计算机操作：从存款账户中取出$700，在支票账户中存入$700。如果一个操作成功，另一个没有，那银行的账目到最后也不会平衡。因此必须有一种方法来确保两个操作都成功或者都失败，这样银行的数据库中就没有任何的不一致性。

事务处理连接单个不可分割的事务中的多个单独的操作，并且确保事务中的所有操作都没有错误或是没有操作。如果一些操作完成但其他操作在完成时发生了错误，事务处理系统会“回滚”事务的所有操作（包括成功的那些），从而消除所有事务的痕迹并将系统恢复到之前处理事务开始时的一致，已知的状态。如果事务的所有操作被成功完成，事务会被系统提交，所有数据库中的改变变为永久性的；一旦这个操作完成事务不能再被回滚。

预防硬件和软件错误的事务处理可能会让一个事务部分完成，如果计算机系统在事务中间崩溃，事务处理系统会保证所有未被提交的事务中的操作会被中止。
通常来说，事务并发发行的。如果他们重叠（例如需要接触数据库的同一部分），就会导致冲突。例如，如果上述银行例子中的顾客在他的存款账户中有$150并尝试在同时将$100转账给另一个人和将$100转到支票账户，只有其中的一个行为能够成立。然而，迫使事务顺序处理是低效的。因此，事务处理的并发实施被编程保证最终结果反映了一个没有冲突的结局，如果以任何顺序执行事务也能得到同样的结果（一种叫做[可串行性]的属性）。在我们的例子中，它表明无论哪个事务第一个发生，转账给另一个人成功或是将钱转到支票账户成功，则另一个将会失败。

## 方法论

所有事务处理系统的基本原理都是一样的。然而术语可以从一个事务处理系统到另一个事务处理系统而变化。下面所用的术语未必都是通用的。

### 回滚

事务处理系统通过记录数据库改动时的中间状态来确保数据库的完整性，然后用这些将数据库恢复到已知的状态，如果事务没有成功提交的话。例如，数据中信息的副本的优先级高于它的改动信息，因为在事务做出任何改动之前会被系统晾在一边（这有时被叫做前映像）。如果在事务被提交之前，他的任一部分出现了问题，那些副本将会被用来恢复数据库到事务刚刚开始的状态。

### 前滚

为所有对数据库管理系统的改动持续记录成为一份单独的日志也是可能的（有时被称为后映像）。他对于失败事务的回滚来说不是必需的，但是在数据库故障事件中对修正数据库管理系统很有用，所以一些事务处理系统也支持。如果数据库管理系统出现了整体故障，需要从最近的备份恢复。备份不会反映事备份之后提交的事务。然而，一旦数据库管理系统被恢复，后映像的日志就能使数据库管理系统到最新状态。任何进程中的事务在失败的同时能被回滚。结果就是数据库处于一个一致，已知的状态包括到故障时刻提交的所有事务的结果。

### 死锁

在一些案例中，两个事务可能在他们处理的过程中，试图同时接入数据库的同一区域，某种程度上阻碍了他们的继续进行。例如，事务A可能接入数据库的区域X，事务B接入数据库的区域Y。如果在那时，事务A尝试接入数据库的区域Y而事务B尝试接入数据库的区域X，死锁就发生了，两个事务都不能继续进行。事务处理系统的设计能够在死锁发生时检测到这些死锁。通常两个事务将会被取消和回滚，然后以不同的顺序自动启动，所以死锁不再会发生。有时，死锁中的一个事务会被取消，回滚，然后在一小段延迟之后自动启动。

死锁也会在三个或多个事务之间发生。涉及越多的事务，他们就越难被侦测到。简要的说就是事务处理系统对检测死锁有一个实际的限制。

### 补偿事务

在提交和回滚机制不可用或不可取的系统中，通常使用补偿事务来撤销失败的事务并将系统恢复到先前的状态。

## ACID 标准

Jim Gray定义了一个可靠的事务系统的属性，首字母缩写为ACID：atomicity（原子性）、consistency（一致性）、isolation（隔离性）、durability（耐久性）。

### 原子性

一个事务对状态的改变是基元的，所有发生的或是不发生的。这些变化包括数据库更改，消息和传感器上的行为。

### 一致性

一致性：事务是对状态的正确转换，以组为单位采取的行动不违反与状态相关联的完整性约束。

### 隔离性

即使事务并发执行，对于每个事务T来看，其他的事务都是在T之前或之后执行，但不是两者都执行。

### 耐久性

一旦事务成功完成（提交），对状态的改变从故障中幸存并被保留。

## 好处

事务处理有以下好处：

* 允许在许多用户之间共享计算机资源。
* 将作业处理的时间转移到计算机资源被占用少的时候。
* 避免了没有人为互动和监督而产生空闲的计算机资源。
* 被用在昂贵的计算机类上来分摊成本，使这些昂贵的资源保持高利用率。

## 实现

标准的事务处理软件，特别是IBM的信息管理系统，最早是在20世纪60年代开发的，并且经常与特定的数据库管理系统紧密耦合。客户端-服务端计算在20世纪80年代实现类似的原则，取得了成功。然而，在最近几年中，分布式客户端-服务端计算已经变得相当难以去维护。随着相应各种线上服务（特别是Web）的事务增长，单个分布式的数据库已经不是一个实用的解决方案。另外，大多数包含一系列程序的线上系统一起操作，而不是单个服务器可以处理事务的严格的客户端-服务端模型。现在，大多数事务处理系统可用于程序级别工作和扩展到大型系统，包括大型机。一个众所周知的（开放）的行业标准是 X/Open分布式事务处理（DTP）（参见JTA，Java事务API）。然而，专利事务处理环境中，例如IBM的CICS还十分流行，虽然CICS也已经升级到包含行业标准了。术语“极端事务处理”（XTP）已经被用来描述具有极其挑战性要求的事务处理系统，特别是吞吐量要求（每秒钟的事务）。这样的系统可以通过分布式或集群式架构来实现。

## 参考

* Nuts and Bolts of Transaction Processing (1999)（页面存档备份，存于互联网档案馆）
* Managing Transaction Processing for SQL Database Integrity（页面存档备份，存于互联网档案馆）
* Transaction Processing（页面存档备份，存于互联网档案馆）

## 进一步阅览

* Gerhard Weikum, Gottfried Vossen, *Transactional information systems: theory, algorithms, and the practice of concurrency control and recovery*, Morgan Kaufmann, 2002, ISBN 1-55860-508-8
* Jim Gray, Andreas Reuter, Transaction Processing — Concepts and Techniques, 1993, Morgan Kaufmann, ISBN 1-55860-190-2
* Philip A. Bernstein, Eric Newcomer, Principles of Transaction Processing, 1997, Morgan Kaufmann, ISBN 1-55860-415-4
* Ahmed K. Elmagarmid (Editor), Transaction Models for Advanced Database Applications, Morgan-Kaufmann, 1992, ISBN 1-55860-214-3