精华内容
下载资源
问答
  • 并发控制

    千次阅读 2018-08-02 18:17:07
    所谓事务,是指用户定义的一个数据库操作序列,这些操作要么全做,要么全不做...事务是并发控制的基本单位,保证事务ACID特性是事务处理的重要任务。 并发操作带来的数据的不一致性问题: 1.丢失修改 两个事务T1...

    所谓事务,是指用户定义的一个数据库操作序列,这些操作要么全做,要么全不做,是一个不可分割的工作单位。
    事务具有四个特性:
    1.原子性 2.一致性(Consistency) 3.隔离性(Isolation)持续性(Durability)

    并发控制概述

    事务是并发控制的基本单位,保证事务ACID特性是事务处理的重要任务。
    并发操作带来的数据的不一致性问题:
    1.丢失修改
    两个事务T1和T2读入同一组数据并修改,T2提交的结果破坏了T1提交的结果,导致T1的修改被丢失。
    2.不可重复读
    不可重复读是指事物T1读取数据后,事务T2执行更新操作,使T1无法再前一次读取的结果。不重复读包括三种结果:
    (1)事务T1读取某一数据后,事务T2对其做了修改,当事务T1再次读该数据时,得到与前一次不同的值。
    (2)事务T1按一定条件从数据库中读取某些数据记录后,事务T2删除了其中部分记录,当T1再次按相同条件读取数据时,发现某些记录神秘消失了。
    (3)事务T1按一定条件从数据库中读取某些数据记录后,事务T2插入了一些记录,当T1再次按照相同条件读取数据时,发现多了一些记录。
    后两种不可重复读有时也称为幻影现象。
    3.读脏数据(Dirty Read)
    读脏数据是指事物T1修改某一数据,并将其写会磁盘,事物T2读取同一数据后,T1由于某种原因被撤销,这时T1已修改过的数据被恢复原值,T2读到的数据与数据库中的数据不一致,则T2读到的数据就为“脏数据”。
    产生上述三类数据不一致的主要原因是并发操作破坏了事务的隔离性。
    并发控制的主要技术有封锁(Locking)、时间戳(Timestamp)和乐观控制法,商用的DBMS一般都采用封锁方法。

    封锁

    所谓封锁就是事务T在对某个数据对象例如表、记录等操作之前,先向系统发出请求,对其加锁。加锁后事务T就对该数据对象有了一定的控制,在事务T释放它的锁之前,其他的事务不能更新此数据对象。
    基本的封锁类型有两种:
    1.排它锁(Exclusive Locks),简称X锁
    2.共享锁(Share Locks),简称S锁
    排它锁又称写锁。若事务T对数据对象A加上X锁,则只允许T读取和修改A,其他任何事务都不能再对A加任何类型的锁,直到T释放A上的锁。
    共享锁又称读锁。若事务T对数据对象A加上S锁,则事务T可以读A但是不能修改A,其他事务只能再对A加S锁,而不能加X锁,直到T释放A上的S锁。

    活锁和死锁

    活锁

    如果事务T1封锁了数据R,事务T2又请求封锁R,于是T2等待。T3也请求封锁R,当T1释放了R上的锁后系统首先批准了T3的请求,T2仍然等待。然后T4又请求封锁R,当T3释放了R上的封锁之后系统又批准了T4的请求…T2有可能永远等待下去,这就是活锁的情形。
    避免活锁采用的方法是先来先服务的策略。

    死锁

    1.死锁的预防

    通常有两种方法:1.一次封锁法 2.顺序封锁法
    一次封锁法:要求每个事务必须一次性将所有要使用的数据全部加锁,否则就不能继续执行。
    存在问题:1.一次就讲以后要用到的全部数据加锁,扩大了封锁的范围,从而降低了系统的并发度。
    2.数据库中的数据是不断变化的,原来不要求封锁的数据,在执行过程中可能会变成封锁对象,所以很难先景区地确定每个事务索要封锁的数据对象。
    顺序封锁法:预先对数据对象规定一个封锁顺序,所有事务都按这个顺序实行封锁。
    存在问题:1.数据库系统中封锁的数据对象极多,并且随数据的插入、删除等操作不断变化,要维护这样的资源的封锁顺序非常困难,成本很高。
    2.事务的封锁请求可以随着事务的执行而动态地决定,很难事先确定每一个事务要封锁那些对象,因此也很难按规定的顺序去施加封锁。
    DBMS在解决死锁的问题上普遍采用的是诊断并解除死锁的方法

    2.死锁的诊断与解除

    1.超时法
    如果一个事务的等待时间超过了规定的时限,就认为发生了死锁。
    不足:1.有可能误判死锁,事务因为其他原因使等待时间超过时限,系统会误认为发生了死锁。
    2.时限若设置得太长,死锁发生后不能及时发现。
    2.等待图法
    事务等待图是一个有向图G=( T, U).T为结点的集合,每个结点表示正在运行的事务,U为边的集合,每条边表示事务的等待情况。
    事务等待情况动态反应了所有事务的等待情况。并发控制子系统周期性地生成事务等待图,并进行检测。如果发现图中存在回路,则表示系统中出现了死锁。
    DBMS的并发控制子系统一旦检测到系统中存在死锁,就要设法解除。通常采用的方法是选择一个处理死锁代价最小的事务,将其撤销,释放此事务持有的所有的锁,使其他事务得以继续运行下去。

    并发调度的可串行性

    DBMS对并发事务不同的调度可能会产生不同的结果,那么什么样的调度是正确的呢?显然,串行调度是正确的。执行结果等价于串行调度的调度也是正确的。这样的调度叫可串行化调度。

    可串行化调度

    定义:多个事务的并发执行是正确的,当且仅当其结果与按某一次序串行的执行这些事务时的结果相同,称这个调度策略是可串行化的。
    可串行性是并发事务正确执行的准则。

    冲突可串行化调度

    冲突操作是指不同的事务对同一个数据的读写操作和写写操作:
    Ri(x)与Wj(x) //事务Ti读x,Tj写x
    Wi(x)与Wj(x) //事务Ti写x,Tj写x
    其他操作是不冲突操作。
    一个调度Sc在保证冲突操作的次序不变的情况下,通过交换两个事务不冲突操作的次序得到另一个调度Sc’,如果Sc’是串行的,称调度Sc为冲突可串行化的调度。一个调度是冲突可串行化,一定是可串行化的调度。
    冲突可串行化调度是可串行化调度的充分条件,不是必要条件。还有不满足冲突可串行化条件的可串行化调度。

    两段锁协议

    在运用封锁方法时,对数据对象加锁时需要约定一些规则,例如何时申请封锁、持所时间、何时释放封锁等。这些规则被称为封锁协议。
    所谓两段锁协议是指所有事务必须分两个阶段对数据项加锁和解锁:
    1.在对任何数据进行读、写操作之前,首先要申请并获得对该数据的加锁
    2.在释放一个封锁之后,事务不再申请和获得任何其他封锁
    两段锁的含义是,事务分为两个阶段,第一个阶段是获得封锁,也称为扩展阶段。在这阶段,事务可以申请获得任何数据项上的任何类型的锁,但是不能释放任何锁。第二个阶段是释放封锁,也称为收缩阶段。在这阶段,事务可以释放任何数据项上的任何类型的锁,但是不能再申请任何锁。
    事务遵守两段锁协议是可串行化的充分条件,而不是必要条件。
    要注意两段锁协议和防止死锁的一次封锁法的异同之处。一次封锁法要求每个事物必须一次将所有要使用的数据全部加锁,否则就不能继续执行。因此一次封锁遵守两段锁协议;但是两段锁协议并不要求事务必须将所有要是有的数据全部加锁,因此遵守两段锁协议的事务可能发生死锁。

    封锁的粒度

    封锁对象的大小称为封锁粒度。封锁对象可以是逻辑单元,也可以是物理单元。以关系数据库为例,封锁对象可以是这样一些逻辑单元:属性值、属性值的集合、元组、关系、索引项、整个索引直至整个数据库;也可以是这样一些物理单元:页、物理记录等。
    如果在一个系统中同时支持多种封锁粒度供不同的事务选择是比较理想的,这种封锁方法称为多粒度封锁。

    多粒度封锁

    多粒度树:多粒度树的根节点是整个数据库,表示最大的数据粒度。叶节点表示最小的数据粒度。
    多粒度封锁协议允许多粒度树种的每个节点被独立地加锁。对一个结点加锁意味着这个结点的所有后裔结点也被加以同样类型的锁。因此,在多粒度封锁中一个数据对可能一两种方式加锁,显示封锁和隐式封锁。
    显示封锁是应事务的要求直接加到数据对象上的封锁;
    隐式封锁是该数据对象没有独立加锁,是由于其上级结点加锁而使该数据对象加上了锁。
    一般地,对某个数据对象加锁,系统要检查该数据对象是哪个有误显示封锁与之冲突;还要检查其所有上级结点,看本事务的显示封锁是否与该数据对象上的隐式封锁冲突;还要检查所有下级结点,看上面的显示封锁是否与本事务的隐式封锁冲突。

    意向锁

    意向锁的含义是如果对一个结点加意向锁,则说明该结点的下层结点正在被加锁;对任一结点加锁时,必须先对他的上层结点加意向锁。
    意向共享锁(IS锁)、意向排它锁(IX锁)、共享意向排它锁(SIX锁)
    IS锁
    如果对一个数据对象加S锁,表示它的后裔结点拟(意向)加S锁。
    IX锁
    如果对一个数据对象加IX锁,表示它的后裔结点拟(意向)加X锁。
    SIX锁
    如果对一个数据对象加SIX锁,表示对它加S锁,再加IX锁,即SIX= S+IX。
    具有意向锁的多粒度封锁方法中任一事务T要对一个数据对象加锁,必须先对它的上层结点加意向锁。申请封锁时应该按自上而下的次序进行;释放封锁时应该按自下而上的顺序进行。

    基于时间戳的协议

    另一种决定事务可串行化次序的方法是事先选定事务的次序。其中最常用的方法是时间戳排序机制。

    时间戳

    对于系统中每个事务Ti,我们把一个唯一的固定时间戳和它联系起来,此时间戳记为TS(Ti)。该时间戳是在事务Ti开始执行前由数据库系统赋予的。若事务Ti已赋予时间戳TS(Ti),此时有一种新事务Ti进入系统,则TS(Ti) < TS(Tj)。实现这种机制可以采用下面这两个简单的办法:
    1.使用系统时钟的值作为时间戳:即事务的时间戳等于该事务进入系统时的时钟值。
    2.使用逻辑计数器,每赋予一个时间戳,计数器增加计数,即事务的时间戳等于该事务进入系统时的计数器值。
    要实现这个机制,每个数据项Q需要与两个时间戳值相关联:
    W-timestamp(Q)表示成功执行write(Q)的所有事务的最大时间戳
    R-timestamp(Q)表示成功执行read(Q)的所有事务的最大时间戳。

    时间戳排序协议

    保证任何有冲突的read或write操作按时间戳顺序执行。该协议运作方式如下:
    1.假设事务Ti发出read(Q)
    a.若TS(Ti) < W-timestamp(Q),则Ti需要读入的Q值已经被覆盖。因此,read操作被拒绝。Ti回滚。
    b.若TS(Ti)>=W-timestamp(Q),则执行read操作,R-timestamp(Q)被设置为R-timestamp(Q)与TS(Ti)两者的最大值。
    2.假设事务Ti发出write(Q)
    a.若TS(Ti) < R-timestamp(Q),则Ti产生的Q值是先前所需要的值,且系统已假定该值不会再产生。因此,write操作被拒绝,Ti回滚。
    b.若TS(Ti) < W-timestamp(Q),则Ti时图写入的Q值已经过时。因此,write操作被拒绝,Ti回滚。
    c.其他情况,系统执行write操作,将W-timestamp(Q)设置为TS(Ti)。
    如果事务Ti由于发出read或write操作而被并发控制机制回滚,则系统赋予它新的时间戳并重新启动。
    时间戳排序协议保证冲突可串行化,这因为冲突操作按时间戳顺序进行处理。
    该协议保证无死锁,因为不存在等待的事务。但是,当一系列冲突的段事务引起长事务反复重启时,可能导致肠事务饿死的现象。如果发现一个事务反复重启,与之冲突的事务应当暂时阻塞,以使该事务能够完成。
    该协议可能产生不可恢复的调度。然而,该协议可以进行扩展,用以下几种方法之一来保证调度可恢复:
    1.在事务末端执行所有的写操作能保证可恢复性和无级联性,这些写操作必须具有下述意义的原子性:在写操作正在执行的过程中,任何事物都不允许访问已写完的任何数据项。
    2.可恢复性和无级联性也可以通过使用一个受限的发封锁形式来保证,由此,对未提交数据项的读操作被推迟到更行该数据项的事务提交之后。
    3.可恢复性可以通过跟踪为提交写操作来单独包装,一个事物Ti读取了其他事物所写的数据,只有在其他事物都提交之后,Ti才能提交。

    基于有效性检查的协议

    有效性检查协议要求每个事物Ti在其生命周期中按两个或三个阶段执行,则取决于事务是一个只读事务还是一个更新事务。
    1.读阶段:在这一阶段中,系统执行事务Ti。个数据项值被读入并保存在事务Ti的局部变量中。所有write操作都是对局部临时变量进行的,并不对数据库进行真正的更新。
    2.有效性检查阶段:对事务Ti进行有效性测试,判断是否可以执行write操作而不违反可串行性。如果事务有效性测试失败,则系统终止这个事务。
    3.写阶段:若事务Ti已通过有效性检查,则保存Ti任何写操作结果的临时就被变量值被复制到数据库中。只读事务忽略这个阶段。
    为了进行有效性检测,我们需要知道事务Ti的各个阶段何时进行。为此,我们将三个不同的时间戳与事务Ti相关联。
    1.Start(Ti):事务Ti开始执行的时间
    2.Validation(Ti):事务Ti完成读阶段并开始其有效性检查的时间
    3.Finish(Ti):事务Ti完成写阶段的时间
    我们利用时间戳Validation(Ti)的值,通过时间戳排序技术决定可串行性排序。因此,值TS(Ti) = Validation(Ti)。并且若TS(Tj) < TS(Tk),则产生的任何调度必须等价于事务Tj出现在Tk之前的某个串行调度。选择Validation(Ti)而不是Start(Ti)作为事务Ti的时间粗是因为在冲突频度很低的情况下期望有更快的响应时间。
    事务Ti的有效性测试要求任何满足TS(Tk) < TS(Tj),的事务Tj必须满足下面两条件之一:
    1.Finish(Tk) < Start(Tj)。因为Tk在Tj开始之前完成其执行,所以可串行性次序得到了保证
    2.Tk缩写的数据项集与Tj所读数据项集不相交,并且Tk的写阶段在Tj开始其有效性检查阶段之前完成。这个条件保证Tk与Tj的写不重叠。因为Tk的写不影响Tj的读,又因为Tj不可能影响Tk的读,从而保证了可串行性次序。
    在有效性检查机制中,由于事务乐观的执行,假定他们能够完成执行并且最终有效,因此也称为乐观的并发控制机制。与之相反,封锁和时间戳排序是悲观的,因为当他们检测到一个冲突时,它们强迫事务等待或回滚,即使该调度有可能是冲突可串行的。

    展开全文
  • 并发控制是数据库中的一大重点,本文就数据库中的并发控制做简要分析和介绍。 在讨论数据库并发之前我们先引入事务的概念: 数据库事务通常包含了一个序列的对数据库的读/写操作(一个单元的一系列SQL语句的集合)。...

    并发控制是数据库中的一大重点,本文就数据库中的并发控制做简要分析和介绍。

    在讨论数据库并发之前我们先引入事务的概念:

    数据库事务通常包含了一个序列的对数据库的读/写操作(一个单元的一系列SQL语句的集合)

    我们引入事务无非是为了实现以下两个目的:

    1. 为数据库操作序列提供一个从失败中恢复到正常状态的方法,同时提供数据库即使在异常状态下仍能保持一致性的方法。(即系统的错误恢复
    2. 当多个应用程序并发访问数据库时,可以在这些应用程序之间提供一个隔离方法,以保证彼此之间的操作不会互相干扰。(即并发数据库访问

    当事务被提交给**数据库管理系统(DataBaseManagerService,DBMS)**之后,DBMS需要确保该事务中的所有操作都成功完成且其结果被永久保存在数据库中,如果事务中有的操作没有成功完成,则事务中的所有操作都需要回滚,回到事务执行前的状态。同时,该事务对数据库或者其他事务的执行不会产生影响,即所有的事务都好像在独立的运行。

    了解了事务的概念后,我们来引入并发,在最原始的单处理机系统中,事务只能一个一个地串行执行,即每个时刻之后一个事务执行,上一个事务执行完成之后下一个事务才有机会执行,如下图(a)所示,这样做的缺点很明显,就是计算机资源的利用率很低(比如A事务需要使用CPU资源,B事务需要使用IO资源,二者所需的资源不冲突,但是在串行方式下同一时刻只能利用到CPU或只能利用到IO,资源使用率很低)。为了提高资源的利用率,出现了一种叫做交叉并发的方式,即让不同事务分时间段进行交叉执行,这样可以减少处理机的空闲时间,如下图(b)所示。image-20190625223920610

    上面描述的是单处理机的情况,可以发现这种情况下没有实现真正的并行运行,导致计算机资源利用率较低,这时就引入了多处理机下的并发执行,即当计算机有多个处理机时,就可以同时在不同的处理机上运行不同的事务,这样做到真正意义上的并发运行,这样做的优点是计算机的资源利用率得到了有效提高,缺点就是由于并发会产生很多串行执行时不会产生的冲突和错误,会引起数据库的不一致性,为了解决这一缺点,我们就需要对数据库中的并发进行控制,这也是我们本文的重点,即数据库系统的并发控制

    并发操作引起的数据不一致性包括三个方面:

    1. 丢失修改(lost update):卖票问题,A代表票的余量,事务X集合事务Y将A读入,假设此时A=10,事务X将票卖出一张即A=A-1=9,将A写入,数据库中A此时为9,事务Y也将票卖出一张即A=A-1=9,将A写入数据库即数据库中此时A=9,可是明明卖出去了两张票,相当于事务X对A的修改丢失了。

    2. 不可重复读(non-repeatable read):不可重复读是指事务T1读取数据后,事务T2对数据库执行更新操作,致使事务T1无法再现前一次读取的结果。具体来说分为以下三类情况

      • T1读取数据后T2对数据进行修改,导致T1之后读取的数值与之前读取的不一样
      • T1读取数据之后T2对数据进行删除,导致T1之后再按相同条件读取的数据少了一部分
      • T1读取数据之后T2对数据进行插入,导致T1之后再按相同条件读取的数据多了一部分

      后两种情况有时也称为幻影/幻读现象。

    3. 读脏数据:事务T1将数据修改后写入数据库,T2此时将数据读取,T2读取后T1又由于某种原因撤销了之前的对数据的修改,导致T2读取的数据与原数据库中的数据不一致,即脏数据

    产生上述三类错误的原因在于并发操作破坏了事务的隔离性,而数据库系统的并发控制就是为了解决这一问题从而保证不同事务之间可以独立执行、各自不受影响,目前并发控制的主要技术有:封锁、时间戳、乐观控制法、多版本并发控制等。

    本文我们讲解目前大多数数据库都在采用的并发控制技术,即**封锁(Locking)**技术。

    封锁

    封锁是实现并发控制的一个非常重要的技术,所谓 封锁就是事务T在对某个数据对象例如表、记录等操作之前,先向系统发出请求,对其加锁,加锁之后事务T就对该数据对象有了一定的控制,在事务T释放该锁之前,其他事务不能对该数据对象进行更新。目前来说数据库系统主要提供两种锁:

    • 排他锁(写锁),exclusive Locks,简称X锁:若事务T对数据对象A加写锁,则只允许T读取修改A,其他事务都不能再对A加任何类型的锁,直到T释放A上的锁为止
    • 共享锁(读锁),Share Locks,简称S锁:若事务T对数据对象A加读锁,则只允许T可以读取不能修改A,其他事务只能再对A加读锁,而不能加写锁,直到T释放A上的读锁为止。

    封锁协议

    在运用X锁和S锁这两种基本封锁对数据对象加锁时,还需要约定一些规则,例如何时申请X锁或S锁、持锁时间、何时释放等,这些规则称为封锁协议

    针对不同的事务隔离级别,有不同的封锁协议,这里介绍四级封锁协议:

    • 一级封锁协议:事务T在修改数据R之前必须先对其加写锁,直到事务结束才释放。一级封锁协议防止了丢失修改,但不能保证可重复读和不读脏数据。
    • 二级封锁协议:在一级封锁协议的基础上增加事务T在读数据R前必须加读锁读完就可以释放。二级封锁协议进一步防止读脏数据,但不能保证可重复读。
    • 三级封锁协议:一级封锁协议的基础上增加事务T在读数据R前必须加读锁,直到事务结束才释放。三阶封锁协议除了防止丢失修改和读脏数据外,进一步防止了不可重复读
    • 四级封锁协议:四级封锁协议是对三级封锁协议的增强,其实现机制也最为简单,直接对事务中所读取或者更改的数据所在的表加表锁,也就是说,其他事务不能 读写 该表中的任何数据。

    活锁和死锁

    **活锁:**事务T1锁住数据D,事务T2等待数据D,事务T1释放数据D的锁时事务T3抢占数据D的锁,事务T2继续等待,事务T3释放数据D的锁时事务T4抢占数据D的锁,事务T2继续等待……这样导致事务T2老是执行不了,这就是活锁的场景。

    避免活锁的方案就是先来先服务,即谁先申请锁,谁先得到锁,即如果事务T2先申请了数据D的锁,这是当数据D的锁释放后一定将数据D的锁给事务T2,而不会给其他事务,这样就保证了不会出现活锁。

    **死锁:**事务T1持有数据D1的锁,还需要数据D2的锁才能继续执行,即在等待数据D2的锁,事务T2持有D2的锁,还需要数据D1的锁,即在等待数据D1的锁,这样事务T1和事务T2相互等待,陷入死锁。

    目前在数据库中解决死锁主要有两类方法:

    1. 采取预防措施来预防死锁
    2. 允许死锁发生,定期采用一定手段检测死锁,若检测到发生了死锁,则将死锁解除

    死锁的预防

    一次封锁法

    将事务执行过程中所使用的数据一次性全部加锁,这样就不会发生某个事务由于等待某个数据的锁而出现死锁的情况。缺点是可能会需要扩大锁的范围,降低并发度。

    顺序封锁法

    预先对数据对象排个序,所有事务都按照这个顺序来实施封锁。

    缺点是维护资源的封锁顺序很困难。

    死锁的诊断与解除

    超时法

    如果某个事务等待某个锁超过一定时间就认为它出现了死锁。

    缺点是如果超时时间设置过短会导致本来没有发生死锁的事务被误判为发生了死锁,如果超时时间设置过大,不能及时发现死锁。

    等待图法

    image-20190625233317014

    如上图,如果T1等待T2,则画一条从T1指向T2的有向边,若T2等待T1,则画一条从T2指向T1的有向边,依次类推,这样就可以构成一个图,如果检测到图中有回路,则说明出现了死锁。

    检测到死锁之后就需要解除死锁,现在一般采用的解除死锁的方法是选择一个处理死锁代价最小的事务进行取消,释放其占有的锁,以使其他事务可以正常执行。

    并发控制的可串行性

    数据库管理系统对并发事物不同的调度可能会产生不同的结果,那么什么样的调度才是正确的呢?很明显,串行调度一定是正确的,而执行结果与串行调度的执行结果一样的调度也是正确的,我们将这样的调度称为可串行化调度

    可串行化调度

    可串行化调度的定义:多个事务的并发执行是正确的,当且仅当其执行结果与按照个顺序串行地执行这些事物时的结果相同,将这种调度策略称为可串行化调度

    其实说白了,就是如果按照当前的调度方案执行完所有事务后,数据库中数据的状态和以任意顺序串行执行所有事务的结果相同,则当前的调度方案就是正确的调度,即可串行化调度(可以将当前调度等价为某个串行化的调度)。

    冲突可串行化调度

    我们首先明确什么是冲突操作,冲突操作是指不同事务同一数据读写操作和写写操作:
    $$

    1. R_i(x)与W_j(x) : 事务T_i读x,事务T_j写\
    2. W_i(x)与W_j(x):事务T_i写x,事务T_j写x
      $$

    除了(1)式中的两组读写组合,其他任何操作都是不冲突的操作

    我们在进行事务调度的时候应该注意,不同事务的冲突操作和同一事务的两个操作时不能交换的,比如(1)式中, 与 R i ( x ) 与 W j ( x ) 与R_i(x)与W_j(x) Ri(x)Wj(x)的顺序不可交换, 与 W i ( x ) 与 W j ( x ) 与W_i(x)与W_j(x) Wi(x)Wj(x)的顺序不可交换。

    现在我们来定义冲突可串行化调度:一个调度Sc,在保证不改变冲突操作的次序的前提下,通过交换不同事务之间的不冲突操作,最后得到了一个可串行化的事务序列,则称Sc为冲突可串行化调度。

    我们来以一个实例进行说明:

    对于调度Sc1=r1(A)w1(A)r2(A)w2(A)r1(B)w1(B)r2(B)w2(B)

    w2(A)r1(B)w1(B)不冲突操作,交换二者得到:Sc2=r1(A)w1(A)r2(A)r1(B)w1(B)w2(A)r2(B)w2(B)

    r2(A)r1(B)w1(B)是不冲突操作,交换二者得到:Sc3=r1(A)w1(A)r1(B)w1(B)r2(A)w2(A)r2(B)w2(B)

    得到的Sc3刚好是以事务T1事务T2的顺序串行执行的结果,所以Sc1冲突可串行化的调度

    学会判断一个调度是否是冲突可串行化的调度后,我们就可以引入如下结论了:

    冲突可串行化调度是可串行化调度的充分条件,也就是说,如果一个调度是冲突可串行化调度,其一定是可串行化调度(但是反过来说是不对的,即如果一个调度室可串行化调度,其不一定是冲突可串行化调度)。

    以上结论可以作为判断一个调度是否是可串行化调度的原则

    展开全文
  • MySQL架构之并发控制

    2018-03-20 08:28:39
    一、为什么需要并发控制 为什么需要并发控制,举个很现实的例子,现数据库中有一张A表,路人甲在读取A表中的一条数据,路人乙恰巧在同一个时刻在对这条数据进行更改(最坏的场景就是删除了),那么这个时候,路人甲...

    一、为什么需要并发控制

        为什么需要并发控制,举个很现实的例子,现数据库中有一张A表,路人甲在读取A表中的一条数据,路人乙恰巧在同一个时刻在对这条数据进行更改(最坏的场景就是删除了),那么这个时候,路人甲那边可能会报错退出,或者是读取不到真实的数据。那么解决这类问题最好的途径就是并发控制了,下面讲一下如何实现并发控制。

    二、并发控制的实现

    2.1读写锁

        在处理并发控制时其实很简单,可以通过实现一个由两种类型的锁组成的锁系统来解决问题,这个两种类型的锁通常被称为共享锁和排他锁,也叫读锁和写锁。

        读锁是共享的,或者说是相互不阻塞的,多个客户在同一个时刻可以同时读取同一个资源,而互不干扰。写锁则是排他的,也就是说一个写锁会阻塞其他的写锁和读锁,这是出去安全策略的考虑,只有这样,才能确保在同一时刻中,只有一个用户在写入,并防止其他用户读取正在写入的同一资源

    2.2锁粒度

        一种提高共享资源并发性的方式就是让锁定对象更有选择性,尽量只锁定需要修改的部分数据,而不是所有资源,问题是加锁也需要消耗资源,锁的各种操作,包括获得锁,检查锁是否已解除、释放等,都会增加系统的开销,如果系统会费大量的时间来管理锁,而不是存取数据,那么系统的性能就会因此受到影响。

        此时所策略应运而生,所谓锁策略,就是在锁的开销和数据的安全性之间寻求平衡,这种平衡当然也会影响性能,大多数商业数据库系统没有提供更多的选择,一般都是行级锁,并以更加复杂的方式来实现,以便在锁比较多的情况下尽可能地提供更好的性能。

        而MySQL确提供了更好的选择,每种MySQL的存储引擎都可以实现自己的锁策略和锁粒度。下面介绍下MySQL中比较重要的两种锁策略。

    2.3MySQL比较重要的两种锁策略

    表锁

        表锁是MySQL中最基本的锁策略,并且是开销最小的策略。它会锁定整张表,一个用户在进行写操作前,会获得写锁,这会阻塞其他用户对该表的所有读写操作。

        另外,写锁是比读锁更有优先级的,也就是在锁队列中,写锁可以插入到读锁前面,反之读锁是不能插入到写锁前面的。

    行级锁

        行级锁可以最大程度地支持并发管理,同时也带来了最大的开销。在我们常用的InnoDB和XtraDB中,实现了行级锁。即只会锁定一行的数据,同样,写锁是比读锁更有优先级。

    展开全文
  • mysql并发控制

    千次阅读 2019-03-06 12:36:35
    因为可重复度保证了每一行的记录的一致性(也就是说事务处理的基本单位是“行”),所以当事务开始时,读取事务开始的行数据版本即可 小疑问: 为什么只有read-commited读取的是行数据的最新版本?为什么因为...

    在这里插入图片描述
    在这里插入图片描述解释: Read uncommitted(未提交读),就是说一个线程修改了某一个数据之后,还没有提交之前,就被其他线程读到修改后的数据,这样一来肯定会产生问题
    Read committed(提交读),(大多数数据库系统的默认隔离级别)就是说A线程修改了结果以后,必须提交之后才能被其他线程读到新结果,在他还没有提交之前,数据还是旧的数据。但是这样有一个纰漏,就是A线程在访问修改该数据的时候,其他线程也有可能随时读取到数据,这样的话,其他线程可能拿到的是旧数据,一旦A线程提交修改以后,其他线程那边的数据立刻刷新(valotile关键字的作用),所以还是可能会出现一些问题
    参考链接: https://blog.csdn.net/qq_40241957/article/details/83653379
    Repeatable read(可重复读):在这里插入图片描述
    Serializable(可串行化):由于它大量的加锁,所以性能低下,虽然可以避免很多数据读取问题。

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    数据库的隔离级别详解参考链接:https://blog.csdn.net/qq_40241957/article/details/83653379
    解释:
    ①为什么read-uncommitted由于是读到未提交的,所以不存在版本的问题?
    答: 因为读未提交可以读到其他事务未提交的更新,每次拿去的都是最新的数据 ,所以版本号永远都是最新的
    ②为什么read-uncommitted隔离级别不能使用mvcc?
    答: 因为读未提交会读取到别人可能回滚的更新数据,所以数据不对,所以不建议使用mvcc
    ③为什么REPEATABLE READ则是读取事务开始时的行数据版本?
    答: 因为可重复度保证了每一行的记录的一致性(也就是说事务处理的基本单位是“行”),所以当事务开始时,读取事务开始的行数据版本即可
    小疑问: 为什么只有read-commited读取的是行数据的最新版本?为什么因为read-uncommited是读未提交的,所以不存在版本问题呢?上述图中最后一个括号里面的(注:事务A,事务B。。。。。。。)是什么意思呢?
    答: read-commited是通过“锁行”的方式来防止其他事务干扰

    在这里插入图片描述
    解释: 什么是意向锁概念?
    例如,当读取表里的页面时,在请求页共享锁(S锁)之前,事务在表级请求共享意向锁。这样可以防止其他事务随后在表上获取排他锁(X锁),修改整个表格。意向锁可以提高性能,因为数据库引擎仅在表级检查意向锁,确定事务是否能安全地获取该表上的锁,而不需要检查表中的每行或每页上的锁以确定事务是否可以锁定整个表。(意向锁是更粗粒度的锁,相当于在最外层,其他事务访问数据之前最先检测到的就是意向锁
    在这里插入图片描述
    5.死锁的解决办法?
    产生死锁后需要由一个事务进行回滚,一般是选择回滚undo量最小的事务,一般是表锁引起死锁,因为其占用大量锁资源

    展开全文
  • 数据库并发控制之并发调度

    千次阅读 2018-10-25 01:08:22
    一、并发调度的可串行性 二、两段锁协议 三、封锁的粒度 四、其他并发控制机制
  • 事务并发控制

    2020-03-26 10:03:18
    在学习几年编程之后,你会发现所有的问题都没有简单、快捷的解决方案,很多问题都需要权衡和妥协,而本文介绍的就是数据库在并发性能和可串行化之间做的权衡和妥协 - 并发控制机制。 如果数据库中的所有事务都是...
  • 一、并发控制概述 并发控制机制的任务: 对并发操作进行正确调度;保证事务的隔离性;保证数据库的一致性 并发操作带来数据不一致性: 丢失修改:两个事务同时读入同一个数据并修改,结果T2的提交破坏了T1提交的...
  • MySQL并发控制

    千次阅读 2019-01-26 21:42:24
    如果数据库中的所有事务都是串行执行的,那么它非常容易...而并发(Concurrency)使一切事情的发生都有了可能,它能够解决一定的性能问题,但是它会带来更多诡异的错误。 引入了并发事务之后,如果不对事务的执...
  • 数据库-并发控制

    万次阅读 多人点赞 2018-09-21 23:52:17
    2. 交叉并发方式:在单处理机系统中,并行事务并行操作轮流交叉运行。 这种并行执行方式称为交叉并发方式。 3. 同时并方式:在多处理机系统中,每个处理机可以运行一个事务,多个处理机可以同时运行多个事务,实现...
  • 火龙果软件工程技术中心 本文内容包括:引言DB2多粒度封锁机制介绍Oracle多粒度锁...1引言在关系数据库(DB2,Oracle,Sybase,Informix和SQLServer)最小的恢复和交易单位为一个事务(Transactions),事务具有ACID(原
  • 目录前言一、并发控制概述二、封锁三、封锁协议...事务是并发控制的基本单位,保证事务ACID特性是事物处理的重要任务,而事务的ACID特性可能遭到破坏的原因之一是多个事务对数据库的并发操作造成的。为保证事务的隔离性
  • 数据库并发控制机制

    2020-07-31 13:45:17
    数据库并发控制机制 数据库的并发控制机制,顾名思义,是用来控制数据库的并发操作的机制。控制的目的是为了保证数据完整和数据一致性。 何为数据一致性?在数据库的并发操作中,多个事务同时读取同一份数据,要...
  • 文章目录1、事务简介2、并发控制2.1 并发执行2.2 可串行化调度(Serializable)3、锁协议3.1 封锁3.2 封锁协议3.2.1 一级封锁协议3.2.2 二级封锁协议3.2.3 三级封锁协议4、活锁和死锁4.1 活锁4.2 死锁4.2.1 死锁的预防...
  • 关系数据库——并发控制

    千次阅读 多人点赞 2019-12-02 14:04:03
    并发控制 多用户数据库:允许多个用户同时使用的数据库(订票系统) 不同的多事务执行方式: 1.串行执行:每个时刻只有一个事务运行,其他事务必须等到这个事务结束后方能运行。 2.交叉并发方式: 单处理机...
  • 本内容涉及的知识图谱如下图所示: 并发控制 并发控制是一个内容庞大的话题,在计算机软件系统中只要在同一时刻存在多个请求同时修改数据的情况,就都会产生并发控制的问题,例如Java中的多线程安全问题等。...
  • 浅谈数据库的并发控制

    万次阅读 2018-09-23 19:58:56
    一、什么是并发控制?   在数据库中,并发控制是指在多个用户/进程/线程同时对数据库进行操作时,如何保证事务的一致性和隔离性的,同时最大程度地并发。 当多个用户/进程/线程同时对数据库进行操作时,会出现3种...
  • 1.数据库并发控制的作用 1.1 事务的概念 在介绍并发控制前,首先需要了解事务。数据库提供了增删改查等几种基础操作,用户可以灵活地组合这几种操作,实现复杂的语义。在很多场景下,用户希望一组操作可以做为一个...
  • 并发控制理论基础 基于锁的并发控制 基于时间戳的并发控制       并发控制理论基础 ▍知识点 并发设计的目标是,既要考虑事务的可串行性,又要考虑并发度 并发控制中的典型问题是数据的一致性 ▍...
  • 数据库——事务与并发控制

    千次阅读 2019-05-22 09:04:34
    二、并发控制概述 2.1事务的并发执行 2.2并发执行导致的问题 2.2.1丢失修改 2.2.2读“脏”数据 2.2.3不可重复读 三、封锁 3.1基本锁类型 3.2封锁协议 3.2.1一级封锁协议 3.2.2二级封锁协议 3.2.3三级封锁...
  • 并发控制技术与前一篇提到的数据库恢复技术是主要的事务处理技术,同时并发控制机制和数据库恢复机制是数据库管理系统(DBMS)的重要组成部分。 在单处理机系统中,事务的并行执行实际上是这...
  • 1 引言 在关系数据库(DB2,Oracle,Sybase,Informix和SQL Server)最小的恢复和交易单位为一个事务(Transactions),事务具有ACID(原子性,一致性,隔离性和永久性)特征。关系数据库为了确保并发用户在存取同一...
  • 所谓事务是用户定义的一个数据操作序列,这些操作可作为一个完整地工作 单元,要么全部执行,要么全部不执行,是一个不可分割的工作单位。 事务与程序的不同:程序是静止的,事务是动态的,是程序的执行而不是程 ...
  • 事务是并发控制的基本单位,保证事务的ACID特性是事务处理的重要任务,而事务的ACID破坏的可能原因之一是多个数据对事务的并发控制造成的。所以为了保证事务的一致性和隔离性,数据库系统需要对并发操作进行正确的...
  • 11.1 并发控制概述 把事务读数据x记为R(x),写数据x记为W(x)。 并发操作带来的数据不一致性包括丢失修改、不可重复读和读“脏”数据。 1. 丢失修改(lost update) 两个事务T1和T2读入同一数据并修改,T2提交的结果...
  • 事务是并发控制的基本单位并发控制的目的:保证事务的隔离性和一致性 任务: 对并发操作进行正确调度 保证事务的隔离性 保证数据库一致性 并发操作带来的数据不一致性: 1、丢失修改:读入同一数据并修改 ...
  • 为了控制 并发事务 之间的相互影响, 解决并发可能带来的数据不一致问题, 数据库的并发控制系统 引入了 基于锁的并发控制(Lock-Based Concurrency Control) 和 基于多版本的并发控制机制 MVCC (Mult-Version ...
  • 为此,提出一种基于细分锁的并发控制方法。对节点的操作进行划分,将最小粒度锁定到节点的操作单元上;对锁的类型进行细分,针对不同的操作对象加上不同的锁,同时设计细分加锁算法。应用结果表明,该方法能有效提高...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 80,966
精华内容 32,386
关键字:

并发控制的最小单元