数据库原理与应用 第 9 章 · 第四节
课程 › 第 9 章 › 第四节 封锁与粒度X 锁和 S 锁LOCK TABLES封锁协议死锁判断死锁活锁小结 版式
第 9 章 数据库并发控制与封锁 · 第四节

封锁及封锁协议

封锁粒度,X 锁和 S 锁,LOCK TABLES,三级封锁协议,死锁与活锁
本 节 知 识 点
  1. 15封锁与封锁粒度
  2. 16X 锁和 S 锁
  3. 17给表加锁的例子(例 9-5、例 9-6)
  4. 18三级封锁协议
  5. 19死锁
  6. 20判断死锁的方法
  7. 21活锁
  8. 22本章小结
15
第 9 章 · 第四节 · 课件第 33、34、35 页合并重做

封锁与封锁粒度

隔离级别说明要达到的效果,封锁是实现它的方法。

9.5 封锁及封锁协议课件第 33、34、35 页合并

封锁与封锁粒度

事务在操作某个数据对象(表、记录等)之前,先请求给它加锁。加锁后,在事务释放锁之前,其他事务不能修改这个数据。
  • 封锁粒度:被封锁的数据对象的大小
  • 锁定的数据越少,发生冲突的可能越小,并发程度越高
  • 选择粒度时要在加锁的开销和并发程度之间权衡
  • MySQL 提供表级锁和行级锁两种粒度
表级锁行级锁
锁定范围整张表正在使用的行
开销小,加锁快大,加锁慢
死锁不会出现会出现
并发程度最低最高
  • InnoDB 表修改数据时自动加行级锁,LOCK TABLES 加的是表级锁
16
第 9 章 · 第四节 · 课件第 36 页重做

X 锁和 S 锁

X 锁排它,S 锁共享。

9.5 封锁及封锁协议课件第 36 页重做

X 锁和 S 锁

锁也叫加锁的事务其他事务
X 锁排它锁、写锁可以读,也可以写不能再加任何锁,直到 X 锁释放
S 锁共享锁、读锁只能读,不能写可以再加 S 锁,不能加 X 锁
相容矩阵
已有的锁请求 X 锁请求 S 锁
X 锁不相容不相容
S 锁不相容相容
没有锁相容相容
给表加锁和解锁
LOCK TABLES 表名 {READ | WRITE}
    [, 表名 {READ | WRITE} …];
UNLOCK TABLES;
  • READ 加 S 锁,WRITE 加 X 锁
  • UNLOCK TABLES 释放当前会话加的全部表锁

试一试两种锁能否同时加上

T1 已加
T2 请求
17
第 9 章 · 第四节 · 课件第 37、38、39 页合并重做

给表加锁的例子(例 9-5、例 9-6)

写锁时别人不能读,读锁时谁都不能写。

9.5 封锁及封锁协议课件第 37、38、39 页合并

给表加锁的例子(例 9-5、例 9-6)

例 9-5 T1 加写锁,T2 读取
-- T1
LOCK TABLES account WRITE;

-- T2,要等待
SELECT * FROM account;

T1 执行 UNLOCK TABLES 后,T2 的查询才返回结果。X 锁保证同一数据不会被同时修改

例 9-6 T1 加读锁
-- T1
LOCK TABLES account READ;
SELECT * FROM account;
UPDATE account SET R = 800
WHERE id = 'account1';  -- 报错 1099

-- T2
SELECT * FROM account;      -- 可以
LOCK TABLES account READ;   -- 可以
UPDATE account SET R = 600
WHERE id = 'account2';  -- 等待
  • 加了读锁的会话自己也只能读,修改这张表报错 1099
  • S 锁允许多个事务同时读,但表上有 S 锁时,任何事务都不能修改数据

T1 解锁之前,T2 的 UPDATE 会一直等待,后面的语句也不能执行。

18
第 9 章 · 第四节 · 课件第 40、41、42、43 页合并重做

三级封锁协议

三级协议一级比一级严,各多防止一种问题。

9.5 封锁及封锁协议课件第 40、41、42、43 页合并

三级封锁协议

封锁时约定的规则,例如何时申请封锁、申请哪种锁、持锁多长时间、何时释放,称为封锁协议。
协议规则能防止
一级修改数据前加 X 锁,直到事务结束才释放丢失更新
二级一级协议,加上读数据前加 S 锁,读完就释放丢失更新、读脏数据
三级一级协议,加上读数据前加 S 锁,直到事务结束才释放丢失更新、读脏数据、不可重复读
  • 事务结束包括正常结束 COMMIT 和非正常结束 ROLLBACK
  • 二级协议读完就释放 S 锁,再读时数据可能已被修改,所以不能保证可重复读
  • MySQL 中 SELECT … FOR SHARE 给读到的行加 S 锁,保持到事务结束

试一试三级封锁协议各能防止什么

协议
能防止的问题

实 验

实验 3-4 读锁保持到事务结束

19
第 9 章 · 第四节 · 课件第 44、45 页合并重做

死锁

事务互相等待对方释放锁,都不能继续执行。

9.5 封锁及封锁协议课件第 44、45 页合并

死锁

两个或多个事务都在等待对方释放锁,谁也不能继续执行,这种情况称为死锁。
例
时间事务 T1事务 T2
t0封锁学生表
t1封锁成绩表
t2请求封锁成绩表,等待
t3请求封锁学生表,等待
t4等待等待
死锁的四个必要条件
  • 互斥:资源在一段时间内只能被一个事务占用
  • 请求与保持:等待新资源时,不释放已占有的资源
  • 不剥夺:事务获得的锁,不能被其他事务强行夺走
  • 循环等待:几个事务首尾相接,互相等待
避免死锁的方法
  • 顺序加锁法:各个事务按相同的顺序访问各张表
  • 需要修改数据时直接申请 X 锁,不要先申请 S 锁
  • 一次加锁法:把要用的数据一次全部加锁

试一试按相同顺序加锁,就不会死锁

加锁顺序
事务 T1 事务 T2 学生表 成绩表 等成绩表 等学生表 T2 等 T1 用完学生表

实 验

实验 3-5 死锁

20
第 9 章 · 第四节 · 课件第 46 页

判断死锁的方法

超时法看等待是否超过时限,等待图法看是否形成回路。

课件第 46 页

重 点

MySQL 用等待图的方法,发现死锁后立即回滚其中一个事务,报错 1213。

21
第 9 章 · 第四节 · 课件第 47 页

活锁

某个事务一直得不到锁,永远处于等待状态。

课件第 47 页

分清楚

现象原因
死锁事务之间互相等待
活锁总是被别的事务抢先

重 点

避免活锁的方法是先来先服务,按请求封锁的先后顺序排队。

22
第 9 章 · 第四节 · 课件第 48 页

本章小结

事务、数据的不一致性、隔离级别、封锁与封锁协议。

课件第 48 页

重 点

隔离级别说明要达到什么效果,封锁协议说明用什么方法达到。

保山学院·人工智能教研室·曹鼎鼎