第5章数据的**性本章从事务和授权两个方面对数据的**性进行初步讨论。在多用户环境下,事务与其他技术协同保证数据操作的一致性,授权保证不让某个用户看到不该看的数据。 数据库系统为用户提供数据管理服务,用户对数据库的要求是: 在任何情况下,多个用户都能可靠地同时对数据库中的数据进行操作并获得一致性的结果。数据库用事务保证单一用户对数据库更新的一致性,用并发控制来保证同时执行的多个事务互不干扰,用故障恢复保证数据库的可靠性。本章会用前面数节简单介���事务和并发控制的概念,具体的实现方法将在第16章介绍。而故障恢复的相关技术将在第17章介绍。本章*后一节将讨论SQL中的授权机制。 5.1事务和锁的概念 事务是数据库中独立的工作单元,是构建应用程序的基本逻辑单位。事务中包含多个数据操作,以完成一项完整的任务。锁是在多用户环境中对数据访问的限制。事务和锁是目前DBMS所广泛采用的并发控制机制。 5.1.1事务的概念 为了构建基于数据库的应用程序,仅靠数据库的增、删、改和查询能力还远远不够。SQL语言本身是非过程的,但对于用户而言,连续的多个SQL语句之间却可能存在着内在的紧密联系,这多个SQL语句组合起来共同完成某项业务的处理工作。 下面以银行转账为例简单解释事务的概念。 例5.1假定有两个账户A和B,它们初始的余额分别为500元和800元。现在要从账户A转100元到账户B,此业务由两个操作构成: 从账户A扣除100元。 向账户B注入100元。在实际业务中,这两个操作构成一笔完整的业务,缺一不可。在数据库中,这两个操作可能对应两条 SQL 语句,这两条SQL语句就构成了一个事务。数据库需要考虑两种情况: 如果两条 SQL 语句全部正常执行,使账户间的平衡得以保证,那么此事务中SQL语句对数据的更新就可以**地写到数据库。 如果发生诸如资金不足、账号错误或硬件故障等问题,导致事务中的一条SQL 语句不能执行,那么已经执行的SQL语句对数据库的影响也必须消除,就好像什么都没执行过一样,这样才能仍然保持账户间的平衡状态。 事务(transaction)是由一系列操作构成的程序执行单元,该单元中所包含的多个操作用来完成一项完整的任务。如果事务成功,在事务中所做的所有操作都会在提交(commit)时完成并且**地成为数据库的一部分。如果事务遇到错误,则必须取消或回滚(rollback, 或称回卷、回退),这样所有的操作都将被消除,就像什么都没有执行过一样。事务作为一个整体,要么成功,要么失败。 为便于从形式上对事务加以说明,本书用两个原语来描述数据库操作。 Read(X): 从数据库中将元素X读取到缓冲区。 Write(X): 将缓冲区中的元素X写到数据库。 例5.2使用上述两个原语描述例5.1的转账事务。Read(A) A=A-100 Write(A) Read(B) B=B+100 Write(B)从例5.2可以看出,如果*后的Write(B)操作失败,不能将元素B的新值写入数据库,那么此时两个账户的余额就分别为400元和800元。客户凭空少了100元,对于银行系统而言,这显然是不允许的。在这种情况下,前面已经做过的操作必须撤销,将两个账户的余额恢复为500元和800元。 在数据库管理系统中,单用户系统一次*多只允许一个用户操作数据库,而多用户系统则允许多个用户同时访问同一数据库。在多用户系统中,多个用户并发操作是经常发生的情况,而事务则是执行这种并发操作的*小控制单元。 数据库原理第5章数据的**性5.1.2事务的ACID特性 从保证数据库完整性的目的出发,数据库管理系统必须维护事务的几个性质,包括原子性(atomicity)、一致性(consistency)、隔离性(isolation)和持久性(durability) ——按照每个性质的英文首字母组合简称为ACID特性。ACID特性强调事务的“全或无”宗旨,使得在可变因素很多时能减少管理负担。 1. 原子性 事务的原子性强调事务是一个不可分割的工作单元,事务中的操作要么都发生,要么都不发生。例如例5.1中构成转账业务的一系列操作必须被当作一个整体来处理,要么全部操作都执行,要么全部操作都不执行,绝不能只执行其中的一部分。 2. 一致性 事务必须使数据库从一个一致性状态变换到另一个一致性状态。 在事务开始前,数据库必定处于一致状态;如例5.1中账户A和B的余额开始时分别为500元和800元,两个账户的金额合计为1300元。当事务正在处理时,数据库可能处于不一致的状态;如写完账户A但还没写账户B时,账户A和B的余额分别为400元和800元,两个账户的金额合计为1200元。但当事务完成后,数据库必须再次回到新的一致状态;例如转账完成后,账户A和B的余额分别为400元和900元,两个账户的金额合计为1300元。 事务的原子性保证了数据库(可能不一致)的中间状态不会*终体现到数据库。一致性保证了数据库操作能够真正体现用户的想法,而用户的想法是否能够体现正确的业务逻辑则是用户(或应用程序)的责任。 事务的原子性和一致性共同保证事务单独执行时的正确性。 3. 隔离性 事务的执行不能被其他事务干扰。每个并发执行的事务对数据进行的更新是彼此隔离的,看起来就像是系统中**的一个事务,它不以任何方式影响其他事务,也不受其他事务的影响。 例5.3假设事务T1执行例5.1的转账业务正处于中间阶段,也就是Write(A)操作已经完成,Write(B)操作尚未执行。此时账户A和B的余额分别为400元和800元,数据库处于一个不一致状态。如果此时事务T2要按照此时各账户的余额为每个账户结算利息,显然账户A和B合起来损失了应该为100元所支付的利息。 事务的隔离性保证一个事务永远也看不到其他事务的中间阶段,确保事务并发执行后的系统状态与这些事务以某种次序串行执行后的状态是等价的。确保事务的隔离性是DBMS的责任,用户不必操心,DBMS中的实现方法将在第16章介绍。 事务的原子性和隔离性共同保证事务并发执行时的正确性。