数据库学习笔记「并发控制」

前言

数据库是一个共享资源,可以供多个用户使用。

多用户数据库系统:允许多个用户同时使用同一个数据库的数据库系统

事务可以一个一个地串行之行,每个时刻只有一个事务运行,其他事务必须等到这个事务结束以后方能运行。

为了充分利用系统资源,发挥数据库共享资源的特点,应该允许多个事务并行地执行

在这样的系统中,同一时刻并发运行的事务可以达到上百个

并发控制概述

事务是并发控制的基本单位

保证事务的ACID特性是事务处理的重要任务

⚠️多个事务对数据库的并发操作可能会造成事务ACID特性遭到破坏

为了保证事务的隔离性一致性,数据库管理系统必须对并发操作进行操作

并发造型带来的数据不一致性

  1. 丢失修改(lost update)

    两个事务\(T_!\)\(T_2\)读入同一数据并修改,\(T_@\)提交的结果破坏了\(T_1\)提交的结果,导致\(T_1\)的修改丢失

  2. 不可重复读(non-repeatable read)

    事务\(T_2\)读取数据后,事务\(T_2\)执行更新操作,使\(T_1\)无法再现前一次读取结果

  3. 读“脏”数据(dirty read)

事务\(T_1\)修改某一数据并将其写回磁盘,事务\(T_2\)读取同一数据后,\(T_1\)由于某些原因被撤销

这时被\(T_1\)修改过的数据恢复原值,\(T_2\)读到的数据就与数据库中的数据不一致


并发控制的主要技术有

  • 封锁(locking)
  • 时间戳(timestamp)
  • 乐观控制(optimistic scheduler)
  • 多版本并发控制(multi-version concurrency control)

封锁

封锁是实现并发控制的一个非常重要的技术

基本的封锁类型有两种:

  • 排他锁(exclusive locks),简称X锁,又称写锁

    若事务\(T\)对数据对象\(A\)加上X锁,则只允许\(T\)读取和修改\(A\)

    其他事务都不能再对\(A\)加任意锁,直到\(T\)释放\(A\)

  • 共享锁(share locks),简称S锁,又称读锁

若事务\(T\)对数据对象\(A\)加上S锁,则事务\(T\)可以读\(A\)但不能修改\(A\)

封锁协议

  • 一级封锁协议

    事务\(T\)在修改数据\(R\)之前先对其加X锁,直到事务结束才释放

    • 可防止丢失修改
    • 不能保证可重复读和不读“脏”数据
  • 二级封锁协议

    一级封锁协议基础上增加事务\(T\)在读取数据\(R\)之前先对其加\(S\)锁,读完后再释放\(S\)

    • 防止丢失修改,还可以进一步防止读“脏”数据
    • 不能保证可重复读(读完即释放\(S\)锁)
  • 三级封锁协议

    在一级封锁协议的基础上增加事务\(T\),在读取数据\(R\)之前必须先对其加\(S\)锁,直到事务结束才释放

    • 防止丢失修改,还可以进一步防止读“脏”数据、不可重复读

活锁和死锁

活锁

与操作系统的饥饿相似,事务处于永远等待

避免活锁的简单方法是采用先来先服务的策略

当多个事务请求封锁同一数据对象时,封锁子系统按请求封锁的先后次序对事务排队

死锁

与操作系统中的死锁同理,多个事务之间循环等待

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

  1. 采用一定措施来预防死锁的发生

    死锁的预防:

    • 一次封锁法:必须一次将所有要使用的数据全部加锁
    • 顺序封锁法:预先对数据对象规定一个封锁顺序,所有事物都按这个顺序实施封锁

    死锁的诊断与解除

    • 超时法:一个事务的等待时间超过了规定的时限,就认为发生了死锁
    • 等待图法:动态地反映了所有事务的等待情况(检查是否有回路,有回落则死锁)
  2. 允许死锁发生,采用一定手段定期诊断系统中有无死锁,若有则解除

posted @ 2021-04-01 14:10  VanGy  阅读(167)  评论(0编辑  收藏  举报