侧边栏壁纸
博主头像
Lin2J博主等级

升级了服务器,访问应该会更加流畅🇨🇳

  • 累计撰写 94 篇文章
  • 累计创建 39 个标签
  • 累计收到 4 条评论

目 录CONTENT

文章目录

浅谈数据库之并发控制

Lin2J
2021-01-16 / 0 评论 / 0 点赞 / 337 阅读 / 3,123 字 / 正在检测是否收录...

事务可以一个一个地串行执行,即每个时刻都只有一个事务在执行。
事务也可以在cpu的支持下并行执行,即每个时刻可能不止一个事务在执行。
并发执行下会发生很多问题,因此需要通过并发控制对事务进行调控,保证数据库系统正确、稳定的运行。
并发控制的技术有:封锁,时间戳,乐观控制法,多版本控制法(MVCC)。
toc

并发下可能发生的事务问题

并发环境下,事务的隔离性难以保证,事务的一致性就会遭到破坏

  1. 丢失修改:事务T1修改一个数据A=10后,事务T2紧接着也修改了A=20,T1再来读取A时,发现不是 10 而是 20
  2. 脏读:事务T1修改了一个数据A=10后,事务T2紧接着读取这个数据A,如果此时T1再撤销对A的修改,那么T2读到的这个数据将是错误的,无意义的
  3. 不可重复读:事务T2读取数据A,得到10,然后T1修改了A=20,此时T2再来读取A时,发现得到的不是预想的10,而是20
  • 产生并发问题主要的原因是事务的隔离性没有控制好,导致一致性不能得到保证,因此可以通过并发控制来保证隔离性。数据库管理系统提供了事务的隔离级别来处理并发时的一致性问题。

基本概念,参考书籍 《数据库系统概论》(第5版)

封锁
  • 封锁粒度

    1. 封锁对象的大小称之为封锁粒度。
    2. 封锁对象可以是
      1. 逻辑单元:属性值,元组,索引,数据库等。
      2. 物理单元:数据页,物理记录等。
    3. 封锁粒度越小,并发程度越高,系统开销越大;反之,封锁粒度越大,并发程度越低,系统开销越小。
  • 多粒度封锁

    1. 多粒度树:根结点是整个数据库,表示最大数据粒度,叶子结点表示最小数据粒度。
    2. 多粒度封锁协议:对于一个结点加锁意味着这个结点的所有后裔都加上同样的锁。如,事务T给一个表加上X锁,那么对于该表内所有的行数据,均有X锁(行锁也是属于T的)。
    3. 显示封锁:应事务要求给当前对象加锁。
    4. 隐式封锁:没有该当前数据对象加锁,但是由于其上级结点有锁,导致该对象也会加上一个跟祖先结点一样的锁。
    5. 显示封锁和隐式封锁的效果是一样的。
  • 在多粒度封锁中,系统要检查某对象是否有加锁,需要先查看其祖先是否有锁,还要再查看子孙结点是否有锁,十分耗时。由此,人们引入一种叫意向锁的锁,该锁的含义是:如果某个结点被添加了意向锁,说明该结点的下层结点正在被加锁。

  • 锁的类型(比较容易乱,知道各种锁的用途就好了)

    1. 排它锁:X锁,事务T获得对象A的X锁后,只允许T对A进行读取和修改。
    2. 共享锁:S锁,事务T获得对象A的S锁后,事务T可以读取但不能修改A。此时,其他事务只能对A加S锁。
    3. 意向锁:()
      1. IS锁:如果一个数据对象添加了IS锁,表示它的后裔结点加了S锁。如,事务T要对某行加上S锁,那么首先要给该行所在的表添加IS锁。
      2. IX锁:如果一个数据对象添加了IX锁,表示它的后裔结点加了X锁。如,事务T要对某行加上X锁,那么首先要给该行所在的表添加IX锁。
      3. SIX锁:如果一个数据对象加上SIX锁,表示对它加S锁,然后加IX锁。如,事务T要对某个表加SIX锁,T就要先对整个表加S锁(这意味着它要读取数据),再加IX锁(这意味着它要修改数据)。
    4. 兼容性(比如有T1加了X锁,T2就不能再加锁了,但是T1可以可以加S锁,用 ‘x’ 表示)
    基本锁意向锁

封锁协议

首先要理解好各个锁的兼容性,X、S锁不兼容指的是不能有两个事务同时对一个数据对象,一个加X锁,一个加S锁。

  • 已经设定了这么多锁类型,接下来就是按照锁的特性,增加一些锁协议。通过这些锁协议,各个事务的执行受到限制,加强对一致性的保证。
  • 一级封锁协议:事务T在修改数据A之前,要对A加X锁,直到事务结束才释放。(由于X锁与其他所不兼容,所以知道事务结束前,都只有T对A有读取和修改的权力,故不会丢失修改)。
  • 二级封锁协议:在一级协议的基础上,事务T要读取A之前,要先对其加S锁,读完后释放S锁。(先加S锁,可以测试是否有其他事务对A加了X锁。如果有,那么T进入等待,直到其他事务完成。这样可以避免脏读、不可修改)。
  • 三级封锁协议:在二级协议的基础上,事务T要读取A之前,要先对其加S锁,知道事务结束后才释放S锁。(因为在事务T执行期间,其他事务不能对A加X锁,因此在这期间,A不会被其他事务修改,可以避免不可重复读、脏读、不可修改)。
两段锁协议
  • 两段锁
    • 拓展阶段:即获得封锁。
    • 收缩阶段:即释放封锁。
  • 可串行化调度:通过并发控制,使得多个事务并发进行的结果,与这组事务串行执行的结果相同。(一开始我们说,串行执行cpu利用率低,所以采用并行执行。这时候,事务同时执行,效率高了,但是结果不受影响,与串行执行一样。)

并发控制机制
  • 乐观控制法:该方法认为,事务执行时冲突是很少发生的,因此让事务自由执行,等到事务提交时,再进行正确性检查,因此该方法又被称为“验证方法”。
  • 多版本控制法:一般在数据表中加上一个数据版本号 version 字段,表示数据被修改的次数。当数据被修改时,version 值加一,当事务A要更新数据时,在读取数据的同时也会读取 version 值。在提交更新时,提交版本必须大于记录当前版本才能执行更新,否则重试更新操作,直到更新成功。(该方法的关键是 “ 提交版本必须大于记录当前版本才能执行更新 ”)
0

评论区