Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

锁与事务的关系

  • 锁是给事务占用的

    • 目的就是避免多并发的事务下,出现数据更新查询的冲突问题
    • 如果没有显式开启事务,那么一条语句就是一个事务,执行完语句后自动提交
  • 一个事务只要没有被提交,它都是一直占有着获取到的锁不放的!!!

    • 所以事务不能持续时间太长,也不能同时的并发量太高,更不能对同一行进行多事务下的多并发

表级锁

  • 【注意】

    • 尽管里面含有ROW字样,但一样是表级锁!!!!
    • 两个事务在同一时刻不能在同一个表上持有属于相互冲突模式的锁,但是,一个事务决不会和自身冲突
  • 4大分类记忆(共8种类型)

    • 极端锁

      • AccessShareLock最软

        • 纯SELECT,只读取而不修改都会获取这个锁
        • 最好相处,只会跟最硬的锁冲突
      • AccessExclusiveLock最硬

        • 触发命令(大操作)
          • DROP
          • TRUNCATE
          • VACUUM FULL
        • 不能相处,拒绝其他所有操作
    • 行级的读写锁

      • 读锁
        • RowShareLock
          • SELECT 搭配 FOR UPDATE 或 FOR SHARE,会获取这个锁
          • 很好相处,只会跟最硬的锁,还有极少出现的EXCLUSIVE冲突
      • 写锁
        • RowExclusiveLock
          • INSERT/UPDATE/DELETE等变更操作某,会获取这个锁
          • 很好相处,只会跟最硬的锁,还有极少出现的EXCLUSIVE,还有创建索引的SHARE冲突
    • 表级(传统)的读写锁

      • ShareLock

        • 触发命令
          • Create index(不带Concurently)
        • 不自斥——可同时创建多个索引
        • 很难相处,只允许其他人获取ACCESS SHARE和ROW SHARE
      • 【极少出现】EXCLUSIVE

        • REFRESH MAT和VIEW CONCURRENTLY
        • 最难相处,只允许最软的锁
    • 特殊的排它锁

      • ShareUpdateExclusiveLock
        • 触发命令
          • VACUUM(不带FULL)
          • ANALYZE
          • Create index (Concurently)
        • 很难相处,只允许其他人获取ACCESS SHARE和ROW SHARE和ROW EXCLUSIVE
      • 【极少出现】SHARE ROW EXCLUSIVE
        • CREATE TRIGGER 创建触发器
        • 很难相处,只允许其他人获取ACCESS SHARE和ROW SHARE

行级锁

  • 分类
    • 软锁
      • FOR KEY SHARE最软
        • 会阻塞其他事务执行修改KEY键值的DELETE或者UPDATE,但不会阻塞其他UPDATE
        • 最好相处,允许各种SHARE和NO KEY UPDATE,在外键检查时会使用此锁
      • FOR SHARE
        • 会阻塞各种UPDATE和DELETE
        • 较好相处,允许各种SHARE
    • 硬锁
      • FOR NO KEY UPDATE
        • UPDATE命令时如果没有获取到FOR UPDATE锁的情况下会获取到该锁,对除主键外的的字段进行更新
        • 较难相处,只允许FOR KEY SHARE
      • FOR UPDATE最硬
        • 可以使得SELECT语句获取行级锁,锁定该行,防止该行在本次的操作过程中,被其他的事务获取锁或者进行更改删除操作
        • 不能相处,拒绝其他所有操作

关于ShareLock和exclusiveLock

  • 含义

    • ShareLock
      • 共享锁,又称读锁
      • 允许其他人读,但不允许其他人写
    • exclusiveLock
      • 排它锁
      • 既不允许其他人读,也不允许其他人写
  • 例子

    • A开启事务a
      • 执行select for share
        • 获取到表T中行L的读锁
        • 读成功
    • B紧接着开启事务b
      • 也执行select for share
        • 也获取到表T中行L的读锁
        • 读成功
      • 然后尝试update 行L
        • 因为A手上拿了读锁
        • 写失败
        • 等A把事务a COMMIT,读锁释放,B才写成功
        • 同时,通过update操作,B获取到了行L的排它锁
    • A再开启事务c
      • 通过select for share
        • 因为B手上有排它锁
        • 读失败
        • 等B把事务b COMMIT,排它锁释放,B才读成功

【问题】select......for update会锁表还是锁行?

死锁问题