展开
拓展 关闭
订阅号推广码
GitHub
视频
公告栏 关闭

锁的分类(一)

  • 简介

  • 从数据操作的类型划分:读锁、写锁

读锁 :也称为 共享锁 、英文用 S 表示。针对同一份数据,多个事务的读操作可以同时进行而不会互相影响,相互不阻塞的。
写锁 :也称为 排他锁 、英文用 X 表示。当前写操作没有完成前,它会阻断其他写锁和读锁。这样就能确保在给定的时间里,只有一个事务能执行写入,
并防止其他用户读取正在写入的同一资源。
对于 InnoDB 引擎,读锁和写锁既可以加在表上,也可以加在行上

2个读锁是兼容的
1个读锁1个写锁是不兼容的
2个写锁是不兼容的

  • 锁定读
# 读的时候加S锁
SELECT ... LOCK IN SHARE MODE;
# 写法2
SELECT ... FOR SHARE;

# 读的时候加X锁
SELECT ... FOR UPDATE;
  • 代码案例
# 案例1:开启2个共享锁
# 打开1个mysql页面
# 开启1个事务
begin
# 读user表的时候加S锁
select * from user for share;
# 当前事务未关闭时,打开第2个mysql页面
# 开启第2个事务
begin
# 读user表的时候加S锁
select * from user for share;
# 可以读取到数据

# 案例2:开启1个共享锁,开启1个排他锁
# 打开1个mysql页面
# 开启1个事务
begin
# 读user表的时候加X锁
select * from user for update;
# 当前事务未关闭时,打开第2个mysql页面
# 开启第2个事务
begin
# 读user表的时候加X锁
select * from user for update;
# 这时第2个mysql页面中会阻塞,因为共享锁和排他锁是不兼容的
# 需要关闭第1个事务
commit
# 这时第2个mysql页面中才查询到数据
  • NOWAIT、SKIP LOCKED语法
# 在SELECT ...FOR UPDATE或SELECT ...FOR SHARE后面添加NOWAIT、SKIP LOCKED语法
# NOWAIT会立即报错返回
# SKIP LOCKED也会立即返回,只是返回的结果中不包含被锁定的行
  • 代码案例
# 案例1:使用NOWAIT
# 打开1个mysql页面
# 开启1个事务
begin
# 读user表的时候加X锁
select * from user for update;
# 当前事务未关闭时,打开第2个mysql页面
# 开启第2个事务
begin
# 读user表的时候加X锁
select * from user for update nowait;
# 这时第2个mysql页面中,因为共享锁和排他锁是不兼容的,会直接返回报错信息

# 案例1:使用SKIP LOCKED
# 打开1个mysql页面
# 开启1个事务
begin
# 读user表的时候加X锁
select * from user for update;
# 当前事务未关闭时,打开第2个mysql页面
# 开启第2个事务
begin
# 读user表的时候加X锁
select * from user for update skip locked;
# 这时第2个mysql页面中,因为共享锁和排他锁是不兼容的,会直接返回没有锁定的行
posted @ 2022-06-29 06:33  DogLeftover  阅读(23)  评论(0编辑  收藏  举报