2008年(239)
分类: Oracle
2008-06-17 23:33:18
为了保证数据完整性,数据库系统要求事务具有以下四个特征:原子性(atomicity)、一致性(consistency)、隔离性(isolation)、持久性(durability),简称为ACID特征。
1. 原子性
事务的原子性,是指整个事务在逻辑上是一个整体,是数据库系统中最小的操作单元,就好象组成生物体的最小单位——原子一样,不可以分割。
事务的原子性,要求由事务中所有操作引起的更新,在数据库中要么全部正确反映出来,要么全部不反映。
仍旧以我们前面提到过的这样一个事务——由帐户A向帐户B转帐——为例,该事务的执行只允许产生以下两种结果:
(1)事务执行成功。帐户A中金额减少,帐户B中金额增加,帐户A和B的总金额保持不变。
(2)事务执行不成功。帐户A和B的金额没有变化。
除此之外的任何结果,都不能被数据库系统所接受。然而,有许多因素可能导致该事务的执行结果,不是以上的两种情况,这主要是因为系统顺序执行事务中的所有操作。对该事务来说,数据库系统按照以下两个操作顺序执行:
(1)帐户A中金额减少
(2)帐户B中金额增加
在第1步操作完成后,数据库中数据处于以下状态:
(1)帐户A中金额减少
(2)帐户B中金额不变
(3)帐户A和B的总金额减少
在这一时刻,数据库系统中的数据并没有反映出现实世界的真实状态,我们把这种状态称为不一致状态。事务在运行过程中出现这种情况是不可避免的。在事务继续执行并最终完成后,数据的不一致状态就解决了。然而,如果在这一时刻系统出现故障,事务的处理被终止,事务中的更新就部分地作用于数据库,事务的原子性被破坏。
现有数据库系统使用事务日志来维护事务的原子性。在事务执行过程中,对事务的所有操作都要记录日志信息。如果由于各种原因事务没能正常完成,数据库系统就使用这些日志信息,进行事务回滚,使数据库恢复到事务执行前的状态,就好象事务没有被运行过一样,从而解决了数据的不一致性。对上面的例子来说,系统需要在事务回滚时向帐户A中增加金额,从而使帐户A和B的总金额保持不变。
2. 一致性
事务的一致性,是指事务对数据的更新,要真实地、正确地反映现实世界中的业务处理。这包含两个方面的含义:
(1)事务的完整性。事务中的操作要么全部完成,要么都不执行,这是通过事务的原子性来实现的。
(2)不能丢失事务。事务对数据所发生的改变,要切切实实地反映在数据库中,不能够丢失。
数据库中数据的正确、一致,是数据库被广泛使用和依赖的前提,其重要性不言而喻。一旦一致性被破坏,其数据就无法使用,数据库就失去了价值。
事务在执行过程中,不可避免会在某一时刻使数据库中的数据不一致,这是由于事务中的操作串行执行、有先有后引起的。保证数据的不一致状态不被用户看到,是数据库系统必须要解决的问题。
事务丢失会由于多个事务的并发执行而引起。在上面的例子中,如果在事务还没有执行对帐户B的更改之前,数据库系统又接收到另外一个事务,也需要更改帐户B中的金额(如:向帐户B中存入现金)。这两个事务的处理都是基于帐户B原有的金额进行,不论两个事务执行的先后顺序,也不论那一个事务首先完成,总有一个事务的更新丢失。帐户B中的金额只是反映最后完成事务的更改,首先完成事务的更改被覆盖了。
数据库系统的并发控制机制,用来实现多个事务之间的调度管理,避免了事务的丢失,我们将在并发控制这一节中进行详细的阐述。
3. 隔离性
事务的隔离性,是指多个事务并发执行,一个事务的执行不会对其它事务的执行产生影响,就好象它们是分开、按顺序执行的一样。
数据库中的数据为很多用户所共享,数据库系统要能够同时处理多个用户发送的请求。事务本身的处理特征,使得数据库系统能够做到这一点:
(1)事务由多个操作组成,一些操作涉及磁盘I/O处理,一些操作涉及CPU处理。
计算机系统中CPU与磁盘可以并行运作,因此I/O活动可以与CPU处理并行进行。利用CPU与I/O系统的并行性,多个事务可以并发执行。当一个事务在一个磁盘上进行读写时,另一个事务可在CPU上运行,而第三个事务又可以在另一个磁盘上进行读写。这样系统的吞吐量增加——即给定时间内执行的事务数增加。相应地,处理器与磁盘的利用率也提高。
(2)事务的执行时间有长有短,所包含的操作也各式各样。
如果事务串行执行,短事务可能得等待它前面的长事务完成,这可能导致难以预测的时延。由于系统中的事务一般是针对数据库中的不同部分进行操作,事务的并发执行,不仅使多个事务可以共享CPU周期与磁盘存取,而且还可以减少不可预测的事务执行时延。
当多个事务并发执行时,即使每个事务都正确执行,数据库的一致性也可能被破坏,上面讲到的事务丢失就是其中的一种情况,还有许多种情况都会造成数据的不一致。
数据库系统可以使用很多技术,来保证事务的并发执行不会破坏数据的正确性,这些技术将在并发控制一节中进行阐述。简单地来说,数据库系统对多个并发事务的调度要做到在逻辑上可串行化,即这些并发事务好象是按照某一个顺序串行执行的。
4. 持久性
事务的持久性,是指事务正确完成后,事务所作的更新需要长久地反映在数据库中,即使数据库系统出现各种软件、硬件故障。
事务处理时,所有的操作在内存中完成。如果系统失败,存放在内存中的数据就要丢失。因此要保证被更新的数据长久化,就必须将数据存入磁盘,这就是数据的落实。数据库系统可以采取以下措施,来保证事务的持久性:
(1)事务的所有更新,在事务结束前就写入磁盘。
(2)将事务操作的日志信息,在事务结束前存入磁盘。数据库系统在出现故障而重新启动后,系统依据日志信息,重新执行事务处理。
对第一种方法,将所有更新写入磁盘,事务才结束。系统需要更多的磁盘I/O操作,事务要等待I/O操作完成才能提交,要花费更多的时间。由于数据为很多用户所共享,最近被处理的数据有很大的可能会再次被使用,这种处理方式会不断地进行数据的磁盘读写,造成数据库系统的低效率。因此,现有数据库系统都没有采用这种方法。
现有数据库系统都是通过记录事务日志,来实现事务的持久性。在事务完成前,系统要求事务的所有日志信息都写入磁盘。如果系统失败而事务所做的更新还没有写入磁盘,系统在重新启动时就使用日志信息重新执行该事务。
由于磁盘I/O的操作速度很慢,要求日志信息写入磁盘之后,才能结束一个事务,同样会影响事务的处理速度。另外,系统以块为单位对磁盘进行读写,在交互式系统中,一个事务的日志信息可能很小,不能添满一个块,从而浪费磁盘空间。为了解决这些问题,一些数据库系统也提供折中的日志组写技术。一个事务在处理完成后,就立即提交,不要求该事务的日志信息写入磁盘。在系统已经执行了多个事务,或者存放日志的内存空间被写满后,数据库系统才将日志信息写入磁盘。
这种日志写方式提高了事务处理速度和用户的响应时间,但对事务的持久性构成了威胁。一旦系统失败,已经提交、但日志信息仍旧存放在内存中的事务,其更新将丢失。有关这种日志写方式的更详细信息,可参见第2.2.5一节。