Oracle数据库-并发控制

来源:互联网 发布:用手机开淘宝店的步骤 编辑:程序博客网 时间:2024/06/05 02:43

为什么要进行并发控制

三种典型的由并发事务引起的数据不一致现象

1.丢失修改:
  以购票为例,一次购票过程中,剩余票数这个字段需要被读取,更新(x=x-1),写入。两个人A、B同时购票,B在A写入新的票数之前读取了票数,则读取的值和A的一样,B和A最终写入的都是同一个值,因此系统售出了2张票,而剩余票数字段只减了1,丢失了一次修改结果。
2.不可重复读:
  是指在数据库访问中,一个事务范围内两个相同的查询却返回了不同数据。
  一种更易理解的说法是:在一个事务内,多次读同一个数据。在这个事务还没有结束时,另一个事务修改了该数据。那么,在第一个事务的两次读数据之间。由于第二个事务的修改,那么第一个事务读到的数据可能不一样,这样就发生了在一个事务内两次读到的数据是不一样的,因此称为不可重复读,即原始读取不可重复。
3.脏读:
  简单地说就是事务A读取到了事务B修改了但还没提交的数据,然后B将该事务回滚了,该数据变成修改前的状态,这时事务A在内存中的数据就是已失效的错误数据,即脏读。
  

什么是事务

  DBMS(数据库管理系统)中的事务是指DBMS提供的控制数据操作的一种手段,通过事务,将一系列的数据库基本操作组合在一起作为整体进行操作和控制,从而保证数据一致性。
  
  例如:“银行转账”事务T:从帐户A转账5000RMB到帐户B上

read(A);A:=A-5000;write(A);read(B);B:=B+5000;write(B);

  如果不使用DBMS的事务,上述过程顺序执行,如果执行到一半就异常退出,则可能发生A帐户减少5000元,而B帐户余额没变的情况,造成损失。而DBMS的事务管理可以保证得到的要么是上述语句全执行的结果,要么是全不执行的结果。
  
  事务的宏观性(应用程序员看到的):
  一个存取或改变数据库内容的程序的一次执行,或者说一条或多条SQL语句的一次执行,被看作一个事务
  事务的微观性(DBMS看到的):
  对数据库的一系列基本操作(读、写)的一个整体性执行
  事务并发执行:多个事务从宏观上看是同时执行的,但其微观上的基本操作则可以是交叉执行的(事务A读数据-事务B读数据-A修改数据-B修改数据-A写数据-B写数据)。数据不一致现象就是由于并发事务微观操作的次序安排不正确产生的。

因此,并发控制就是通过事务微观交错执行顺序的正确安排,保证事务宏观上的独立性、完整性和正确性。

(DBMS中)事务的特性:ACID

  1.原子性(Atomicity):DBMS能够保证事务的一组更新操作是原子不可分的,即对DB而言,要么全执行,要么全不执行。
  2.一致性(Consistency):DBMS保证事务的操作状态是正确的,符合一致性操作规则,不能出现数据不一致现象。它其实是由隔离性来保证的。
  3.隔离性(Isolation):DBMS保证并发执行的多个事务之间不受影响,即使并发执行,也相当于先执行了一个,再执行下一个。
  4.持久性(Durability):DBMS保证已提交事务的影响是持久的(写到了磁盘上,不能丢失),被撤销事务的影响是可恢复的(事务被撤销了以后,对磁盘上的数据是没有影响的)。

  DBMS通过事务管理器来产生事务,并对事务的时间戳进行管理,管理事务的一系列微观操作。通过事务调度器对所有事务的操作产生一个读写操作的合理序列(即调度),保证事务的一致性。

事务调度与可串行性

  首先介绍一种表达事务调度的模型

  其中:rT(A):事务T读A,wT(A):事务T写A
    T1:r1(A);w1(A);r1(B);w1(B)
  表示T1事务中发生了“读A-写A-读B-写B”的过程。

  通过这种模型,可以判断事务是不是可串行化的。

冲突可串行性

  冲突:调度中一对连续的动作,如果它们的顺序交换,那么涉及的事务中至少有一个事务的行为会改变,那么称他们是冲突的。
  因此,有冲突的两个操作是不能交换次序的,没有冲突的两个事务是可以交换的。
  几种冲突的情况:
  1.同一事务的任何两个操作都是冲突的,因为事务是由应用程序员制定好的,操作顺序不能改变。
  

  2.不同事务对同一元素的两个写操作是冲突的,即wi(X)wj(X),如果调换顺序,写入的最终内容就发生改变了。
  3.不同事务对同一元素的一读一写操作是冲突的,如ri(X)wj(X),先读X再写X,与先写X再读X,读到的内容会不同。
  冲突可串行性:一个调度,如果通过交换相邻两个无冲突的操作能够转换到某一个串行的调度,则称此调度为冲突可串行化的调度。例如:  
r1(A);w1(A);r2(A);w2(A);r1(B);w1(B);r2(B);w2(B)
  是一个典型的并发调度,通过以下四步对操作次序的转换,可以得到串行的调度:  
r1(A);w1(A);r2(A);r1(B);w2(A);w1(B);r2(B);w2(B)
  
r1(A);w1(A);r1(B);r2(A);w2(A);w1(B);r2(B);w2(B)
  
r1(A);w1(A);r1(B);r2(A);w1(B);w2(A);r2(B);w2(B)

  可见,最后一步变成了串行化的调度,先执行事务1,再执行事务2:  
r1(A);w1(A);r1(B);w1(B);r2(A);w2(A);r2(B);w2(B)
  冲突可串行性是比可串行性严格的概念,满足冲突可串行性,一定满足可串行性,反之不然。例如:  
w1(Y);w2(Y);w2(X);w1(X);w3(X)
  显然不是满足冲突可串行性的,但是如果把w1(X)移到第二个位置,实际上最后写X的还是w3(X),结果不变,因此这个操作虽然引起冲突,但 也是可串行化的

  并发调度的正确性:当且仅当在这个并发调度下所得到的新数据结果与分别串行地运行这些事务所得到的新数据完全一致,则说调度是正确的。

(笔者有时间可能会继续介绍并发控制方法:基于锁、时间戳、有效性确认的并发控制)