事务处理用于有效记录某机构感兴趣的业务活动(称为
事务)的
数据处理(例如
销售、供货的定购或货币传输)。通常,
联机事务处理 (OLTP) 系统执行大量的相对较小的事务。
事务处理
在许多大型、关键的应用程序中,计算机每秒钟都在执行大量的任务。更为经常的不是这些任务本身,而是将这些任务结合在一起完成一个业务要求,称为
事务。如果能成功地执行一个任务,而在第二个或第三个相关的任务中出现错误,将会发生什么?这个错误很可能使系统处于不一致状态。这时
事务变得非常重要,它能使系统摆脱这种不一致的状态。
用户信息控制系统(
CICS)、Tuxedo和TopEnd等产品都是
事务处理系统的例子,它们为应用程序提供事务服务。
事务是一个最小的工作单元,不论成功与否都作为一个整体进行工作。
不会有部分完成的
事务。由于
事务是由几个任务组成的,因此如果一个事务作为一个整体是成功的,则事务中的每个任务都必须成功。如果
事务中有一部分失败,则整个事务失败。
当
事务失败时,系统返回到事务开始时的状态。这个取消所有变化的过程称为“
回滚”( rollback )。例如,如果一个
事务成功更新了两个表,在更新第三个表时失败,则系统将两次更新恢复原状,并返回到原始的状态。
保持应用程序的完整性
任何应用程序的关键是要确保它所执行的所有操作都是正确的,如果应用程序仅仅是部分地完成操作,那么应用程序中的数据,甚至整个系统将会处于不一致状态。例如,看一下银行转账的例子,如果从一个帐户中提出钱,而在钱到达另一个帐户前出错,那么在此应用程序中的数据是错误的,而且失去了它的完整性,也就是说钱会莫名其妙地消失。
克服这种错误有两种方法:
在传统的编程模型中,开发者必须防止任何方式的操作失败。对任何失败点,开发者必须加上支持应用程序返回到这一操作开始时的状态的措施。换句话说,开发者必须加入代码使系统能够在操作出现错误时恢复原状(撤消)。
更为简单的方法是在
事务处理系统的环境之内进行操作,事务处理系统的任务就是保证整个事务或者完全成功,或者什么也不做。如果
事务的所有任务都成功地完成,那么在应用程序中的变化就提交给系统,系统就处理下一个事务或任务。如果操作中某一部分不能成功地完成,这将使系统处于无效的状态,应
回滚系统的变化,并使应用程序返回到原来的状态。
事务处理系统的能力就是将完成这些操作的知识嵌入到系统本身。开发者不必为将系统恢复原状编写代码,需要做的只是告诉系统执行任务是否成功,剩下的事情由
事务处理系统自动完成。
在帮助开发人员解决复杂的问题时,
事务处理系统的另一好处是其ACID属性。
ACID属性
当
事务处理系统创建事务时,将确保事务有某些特性。组件的开发者们假设
事务的特性应该是一些不需要他们亲自管理的特性。这些特性称为ACID特性。
ACID就是:
原子性(Atomicity )、一致性( Consistency )、隔离性( Isolation)和持久性(Durabilily)。
1. 原子性
原子性属性用于标识
事务是否完全地完成,一个
事务的任何更新要在系统上完全完成,如果由于某种原因出错,事务不能完成它的全部任务,系统将返回到事务未开始的状态。
让我们再看一下银行转帐的例子。如果在转帐的过程中出现错误,整个事务将会
回滚。只有当
事务中的所有部分都成功执行了,才将事务写入磁盘并使变化永久化。
为了提供
回滚或者撤消未提交的变化的能力,许多
数据源采用
日志机制。例如,SQL Server使用一个预写
事务日志,在将数据应用于(或提交到)实际数据页面前,先写在事务日志上。但是,其他一些数据源不是
关系型数据库管理系统(RDBMS),它们管理未提交
事务的方式完全不同。只要
事务回滚时,数据源可以撤消所有未提交的改变,那么这种技术应该可用于管理事务。
2. 一致性
事务在系统完整性中实施一致性,这通过保证系统的任何事务最后都处于有效状态来实现。如果
事务成功地完成,那么系统中所有变化将正确地应用,系统处于有效状态。如果在
事务中出现错误,那么系统中的所有变化将自动地
回滚,系统返回到原始状态。因为
事务开始时系统处于一致状态,所以现在系统仍然处于一致状态。
再让我们回头看一下银行转帐的例子,在帐户转换和资金转移前,帐户处于有效状态。如果
事务成功地完成,并且提交事务,则帐户处于新的有效的状态。如果
事务出错,终止后,帐户返回到原先的有效状态。
记住,
事务不负责实施
数据完整性,而仅仅负责在事务提交或终止以后确保数据返回到一致状态。理解
数据完整性规则并写代码实现完整性的重任通常落在开发者肩上,他们根据业务要求进行设计。
当许多用户同时使用和修改同样的数据时,
事务必须保持其数据的完整性和一致性。
在隔离状态执行
事务,使它们好像是系统在给定时间内执行的唯一操作。如果有两个
事务,运行在相同的时间内,执行相同的功能,
事务的隔离性将确保每一事务在系统中认为只有该事务在使用系统。
这种属性有时称为
串行化,为了防止
事务操作间的混淆,必须串行化或序列化请求,使得在同一时间仅有一个请求用于同一数据。
重要的是,在隔离状态执行
事务,系统的状态有可能是不一致的,在结束事务前,应确保系统处于一致状态。但是在每个单独的
事务中,系统的状态可能会发生变化。如果事务不是在隔离状态运行,它就可能从系统中访问数据,而系统可能处于不一致状态。通过提供事务隔离,可以阻止这类事件的发生。
在银行的示例中,这意味着在这个系统内,其他过程和
事务在我们的事务完成前看不到我们的事务引起的任何变化,这对于终止的情况非常重要。如果有另一个过程根据帐户余额进行相应处理,而它在我们的
事务完成前就能看到它造成的变化,那么这个过程的决策可能建立在错误的数据之上,因为我们的
事务可能终止。这就是说明了为什么
事务产生的变化,直到事务完成,才对系统的其他部分可见。
隔离性不仅仅保证多个
事务不能同时修改相同数据,而且能够保证事务操作产生的变化直到变化被提交或终止时才能对另一个事务可见,并发的事务彼此之间毫无影响。这就意味着所有要求修改或读取的数据已经被锁定在
事务中,直到事务完成才能释放。大多数数据库,例如SQL Server以及其他的RDBMS,通过使用锁定来实现隔离,
事务中涉及的各个
数据项或数据集使用锁定来防止并发访问。
4. 持久性
持久性意味着一旦
事务执行成功,在系统中产生的所有变化将是永久的。应该存在一些检查点防止在系统失败时丢失信息。甚至硬件本身失败,系统的状态仍能通过在
日志中记录
事务完成的任务进行重建。持久性的概念允许开发者认为不管系统以后发生了什么变化,完成的
事务是系统永久的部分。
在银行的例子中,资金的转移是永久的,一直保持在系统中。这听起来似乎简单,但这,依赖于将数据写入磁盘,特别需要指出的是,在
事务完全完成并提交后才写入磁盘的。
所有这些
事务特性,不管其内部如何关联,仅仅是保证从事务开始到事务完成,不管事务成功与否,都能正确地管理事务涉及的数据。
数据库事务处理
数据库
数据库的更新通常都是由客观世界的所发生的事件引起的。为保证数据库内容的一致,就要将数据库的一组操作作为一个整体来进行,要么全部成功完成,要么全部失败退出。如果由于
故障或其它原因而使一组操作中有一些完成,有一些未完成,则必然会使得数据库中的数据出现不一致,从而使得数据库的完整性受到破坏。因此,更新操作序列必须作为一个整体在DBMS执行时出现,即“要么全做,要么全不做”。SQL提供了
事务处理的机制,来帮助DBMS实现上述的功能。
事务处理
事务处理(TRANSACTION)是由一个或多个SQL语句序列结合在一起所形成的一个逻辑处理单元。
事务处理中的每个语句都是完成整个任务的一部分工作,所有的语句组织在一起能够完成某一特定的任务。DBMS在对
事务处理中的语句进行处理时,是按照下面的约定来进行的,这就是“事务处理中的所有语句被作为一个原子工作单位,所有的语句既可成功地被执行,也可以没有任何一个语句被执行”。DBMS负责完成这种约定,即使在
事务处理中应用程序异常退出,或者是硬件出现故障等各种意外情况下,也是如此。在任何意外情况下,DBMS都负责确保在系统恢复正常后,数据库内容决不会出现“部分
事务处理中的语句被执行完”的情况。
sql语言
sql语言为
事务处理提供了两个重要的语句,它们是COMMIT和ROLLBACK语句。它们的使用格式是:
COMMIT WORK
ROLLBACK WORK
COMMIT语句用于告诉DBMS,
事务处理中的语句被成功执行完成了。被成功执行完成后,数据库内容将是完整的。而ROLLBACK语句则是用于告诉DBMS,
事务处理中的语句不能被成功执行。这时候,DBMS将恢复本次
事务处理期间对数据库所进行的修改,使之恢复到本次事务未处理的状态。