zoukankan      html  css  js  c++  java
  • 数据库系统原理---封锁

    封锁

    封锁粒度

      MySQL中提供了两种封锁粒度:行级锁表级锁

      应该尽量的只锁定需要修改的那部分数据,而不是所有的资源,锁定的数据量越少,发生锁争用的可能性就越小,系统的并发程度就越高。

    加锁需要消耗资源,锁的各种操作(包括锁的获取,释放锁,以及检查锁状态)都会增加系统的开销。因此封锁粒度越小,系统的开销就越大

    在选择封锁粒度的时候,需要再锁开销和并发程度之间做一个权衡。

    封锁类型

    1.读写锁
    • 排它锁(Exclusive),简写为X锁,又称为写锁
    • 共享锁(Shared),简写为S锁,又称为读锁

    有以下两个规定:

    • 一个事务对数据对象A加了X锁,就可以对A进行读取和修改。加锁期间任何事务不能对A加任何锁。
    • 一个事务对数据对象A加了S锁,就可以对A进行读取操作,但是不能进行更新操作。加锁期间其他事务能对A加S锁,但是不能对A加X锁。

    锁的兼容关系如下:

    --- X锁 S锁
    X锁 x x
    S锁 x
    2.意向锁

      使用意向锁(Intension Locks)可以更容易支持多粒度封锁

      在存在行级锁和表级锁的情况下,事务T要想给表A加X锁,就需要先检查是否有其他事务对表A或者表A中任意一行加了锁,那么就需要对表A的每一行都检测一次,这是非常耗时的。

      意向锁在原来的X/S锁上引入了IX/IS,IX/IS都是表锁,用来表示一个事务想要在表中的某个数据行上加X锁或S锁,有以下两个规定:

    • 一个事务在获得某个数据行对象的S锁之前,必须先获得表的IS锁或者更强的锁。
    • 一个事务在获得某个数据行对象的X锁之前,必须先获得表的IX锁。

      通过引入意向锁,事务T想对表A加X锁,只需要先检测是否有其他的事务对表A加了X/IX/S/IS锁,如果加了就表示有其他的事务正在使用这个表或者这个表中的某一行的锁,因此事务T加X锁失败。

    各种锁的兼容关系如下:

    -- X IX S IS
    X x x x x
    IX x x x
    S x x
    IS x

    解释如下:

    • 任意的IS/IX锁之间都是兼容的,因为它们只是表示想要对表加锁,而不是真正的加锁
    • S锁只与S锁和IS锁兼容,也就是说事务T想要对数据加S锁,其他的事务可以已经获得对表或者表中的行的S锁。

    封锁协议

    1.三级封锁协议

    一级封锁协议

      事务T要修改数据A必须加X锁,直到T结束才能释放锁。

      可以解决丢失修改问题,因为不能同时有两个事务对同一个数据进行修改,那么事务的修改就不会被覆盖。

    T1 T2
    lock-X(A)
    read A=20
    loak-X(A)
    wait
    write A=19 .
    commit .
    unlock X(A) .
    obtain
    read A=19
    write A=21
    commit
    unlock-X(A)

    二级封锁协议

      在一级的基础上,要求读取数据A时必须加S锁,读取完成马上释放S锁。

    ​ 可以解决读脏数据问题,因为如果一个事务在对数据A进行修改,根据1级封锁协议,会加X锁,那么就不能再加S锁了,也就是不会读入数据。

    T1 T2
    lock-X(A)
    read A=20
    write A=19
    lock-S(A)
    wait
    rollback .
    A=20 .
    unlock-X(A) .
    obtain
    read A=20
    unlock-S(A)
    commit

    三级封锁协议

      在二级的基础上,要求读取数据A时必须加S锁,直到事务结束了才能释放S锁。

    可以解决不可重复读的问题,因为读A时,其他事务不能对A加X锁,从而避免了在读的期间数据发生改变。

    T1 T2
    lock-S(A)
    read A=20
    lock-X(A)
    wait
    read A=20 .
    commit .
    unlock-S(A) .
    obtain
    read A=20
    write A=19
    commit
    unlock-X(A)
    2.两段锁协议

      加锁和解锁分为两个阶段进行。

      可串行化调度是指,通过并发控制,使得并发执行的事务结果与某个串行执行的事务结果相同。

      事务遵循两段锁协议是保证可串行化调度的充分条件。例如以下操作满足两段锁协议,它是可串行化调度。

      lock-X(A).....lock-S(B).....unlock-X(A)......unlock-S(B)

      但是不是必要条件,例如以下操作不满足两段锁协议,但是它还是可串行化调度。

      lock-X(A).....unlock-X(A).....lock-S(B)......unlock-S(B)

    MySQL隐式与显式锁定

      MySQL的InnoDB存储引擎采用两段锁协议,会根据隔离级别在需要的时候自动加锁,并且所有的锁都是在同一时刻被释放,这被称为隐式锁定。

      InnoDB也可以使用特定的语句进行显示锁定:

    SELECT ... LOCK In SHARE MODE;
    SELECT ... FOR UPDATE;
    

  • 相关阅读:
    软件测试中桩模块与驱动模块的概念与区别(转载),打桩
    DataFactory使用和注意,排列组合
    SCWS中文分词,功能函数实例应用
    按指定长度截取中英文混合字符串
    CSS截取中英文混合字符串长度
    使DIV相对窗口大小左右拖动始终水平居中
    浮动5-常用列表显示(案例)
    多选项卡切换原理
    使当前对象相对于上层DIV 水平、垂直居中定位
    使图片相对于上层DIV始终水平、垂直都居中
  • 原文地址:https://www.cnblogs.com/yjxyy/p/10797857.html
Copyright © 2011-2022 走看看