我的编程空间,编程开发者的网络收藏夹
学习永远不晚

理解共享锁和排它锁

短信预约 信息系统项目管理师 报名、考试、查分时间动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

理解共享锁和排它锁

理解共享锁和排它锁

1.2 例子:

共享锁事务读取

以不同的 session 来举例:

a:

start transaction;    
select * from demo where id = 1 lock in share mode;

b:

start transaction;    
select * from demo where id = 1 lock in share mode;

此时 a 和 b 都可以正常获取结果,那么再加入 c 排他锁读取尝试

c:

start transaction;    
select * from demo where id = 1 for update;

在 c 中则无法获取数据,直到超时或其它事物 commit

共享锁事务更新

a:

update demo set name = "xxx" where id = 1;

可以很快获取执行结果。当 b 再次执行修改 id=1 的语句时:
b:

update demo set name = "yyy" where id = 1;

就会出现死锁或者锁超时,错误如下:

Deadlock found when trying to get lock; try restarting transaction

或者:

Lock wait timeout exceeded; try restarting transaction

必须等到 a 完成 commit 动作后,b 才会正常执行,如果此时多个 session 并发执行,可想而知出现死锁的几率将会大增。

c 则更不可能

1.3应用场景

拿mysql官方文档的例子来说,一个表是child表,一个是parent表,假设child表的某一列child_id映射到parent表的c_child_id列,那么从业务角度讲,此时我直接insert一条child_id=100记录到child表是存在风险的,因为刚insert的时候可能在parent表里删除了这条c_child_id=100的记录,那么业务数据就存在不一致的风险。

正确的方法是再插入时执行select * from parent where c_child_id=100 lock in share mode,锁定了parent表的这条记录,然后执行insert into child(child_id) values (100)就ok了。

1.4 小结

  • 允许其它事务也增加共享锁读取
  • 不允许其它事物增加排他锁 (for update)
  • 当事务同时增加共享锁时候,事务的更新必须等待先执行的事务 commit 后才行,如果同时并发太大可能很容易造成死锁

共享锁,事务加多少,都能读。修改是唯一的,必须等待前一个事务 commit,才可以下个修改

2.排它锁

2.1 概念

当一个事物加入排他锁后,不允许其他事务加共享锁或者排它锁读取,更加不允许其他事务修改加锁的行。

2.2 例子

排他锁不同事务之间的读取

同样以不同的 session 来举例

a:

start transaction;
select * from demo where id = 1 for update;

b:

start transaction;
select * from demo where id = 1 for update;

当 a 执行完成后,再次执行 b,此时 b 也会卡住,无法立刻获取查询的数据。直到出现超时

Lock wait timeout exceeded; try restarting transaction

或 a commit 才会执行

那么再使用 c 加入共享锁尝试

select * from demo where id = 1 lock in share mode;

结果也是如此,和 b 一样,超时或等待 a commit

Lock wait timeout exceeded; try restarting transaction

排他锁事务之间的修改

当在 a 中执行 update 语句:

update demo set name ="xxx"  where id = 1;

可以正常获取结果,接着在 b 中执行修改

update demo set name = "yyy" where id = 1;

则会卡住直接超时或 a commit, 才会正常吐出结果

c 也很明显和 b 一样的结果,这里就不多赘述

2.3应用场景

如果是同一张表的应用场景,举个例子,电商系统中计算一种商品的剩余数量,在产生订单之前需要确认商品数量>=1,产生订单之后应该将商品数量减1。

1 select amount from product where product_name="XX";  
2 update product set amount=amount-1 where product_name="XX";  

显然1的做法是是有问题,因为如果1查询出amount为1,但是这时正好其他session也买了该商品并产生了订单,那么amount就变成了0,那么这时第二步再执行就有问题。使用排它锁就可以避免这种问题:

select * from demo for update

2.4 小结

  • 事务之间不允许其它排他锁或共享锁读取,修改更不可能
  • 一次只能有一个排他锁执行 commit 之后,其它事务才可执行

不允许其它事务增加共享或排他锁读取。修改是唯一的,必须等待前一个事务 commit,才可以下一个修改

最后

lock in share mode适用于两张表存在业务关系时的一致性要求,for  update适用于操作同一张表时的一致性要求。

— —感谢浏览♥

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

理解共享锁和排它锁

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

理解共享锁和排它锁

1.2 例子:共享锁事务读取以不同的 session 来举例:a:start transaction; select * from demo where id = 1 lock in share mode;b:start transaction;
理解共享锁和排它锁
2014-06-24

MySQL的表级锁,行级锁,排它锁和共享锁

目录前言一、表级锁&行级锁二、排它锁&共享锁1. 测试不同事务之间排它锁和共享锁的兼容性2. 测试行锁加在索引项上三、串行化隔离级别测试前言如果我们和面试官聊到事务的问题,怎么回答呢?先说下事务是什么,因为我们业务是比较复杂的,不可能一
2022-07-14

MySQL的意向共享锁、意向排它锁和死锁

目录一、InnoDB的表级锁二、意向共享锁和意向排它锁三、死锁1. 数据库中的死锁2. 死锁场景以及解决方法3. 操作三、锁的优化建议一、InnoDB的表级锁在绝大多数情况下应该使用行锁,因为事务和行锁往往是选择InnoDB的理由,但个别
2022-07-14

MySQL的表级锁,行级锁,排它锁和共享锁是什么

这篇文章主要介绍“MySQL的表级锁,行级锁,排它锁和共享锁是什么”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“MySQL的表级锁,行级锁,排它锁和共享锁是什么”文章能帮助大家解决问题。前言先说下事
2023-07-02

MySQL表锁、行锁、排它锁及共享锁怎么使用

这篇文章主要介绍“MySQL表锁、行锁、排它锁及共享锁怎么使用”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“MySQL表锁、行锁、排它锁及共享锁怎么使用”文章能帮助大家解决问题。一、事务隔离机制的选
2023-06-29

MySQL的意向共享锁、意向排它锁和死锁是什么

本篇内容介绍了“MySQL的意向共享锁、意向排它锁和死锁是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!一、InnoDB的表级锁在绝大多
2023-07-02

(8)MySQL进阶篇SQL优化(InnoDB锁-共享锁、排他锁与意向锁)

1.锁的分类锁(Locking)是数据库在并发访问时保证数据一致性和完整性的主要机制。之前MyISAM锁章节已经讲过锁分类,而InnoDB锁按照粒度分为锁定整个表的表级锁(table-level locking)和锁定数据行的行级锁(row-level loc
(8)MySQL进阶篇SQL优化(InnoDB锁-共享锁、排他锁与意向锁)
2022-02-17

java Semaphore共享锁实现原理解析

这篇文章主要为大家介绍了Semaphore共享锁实现原理解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2023-01-09

一文搞懂Mysql中的共享锁、排他锁、悲观锁、乐观锁及使用场景

目录一、常见锁类型二、mysql引擎介绍三、常用引擎间的区别 四、共享锁与排他锁五、排他锁的实际应用六、共享锁的实际应用七、死锁的发生八、另一种发生死锁的情景九、死锁的解决方式十、意向锁和计划锁十一、乐观锁和悲观锁总结一、常见锁类型表级锁
2022-07-04

解锁数据共享:JavaScript JSONP指南

JSONP(JSON with Padding)是一种跨域数据共享技术,允许浏览器从其他域加载 JSON 数据。它广泛用于现代网络应用程序中,为开发人员提供了灵活性和安全性。
解锁数据共享:JavaScript JSONP指南
2024-02-28

深入理解java内置锁(synchronized)和显式锁(ReentrantLock)

synchronized 和 Reentrantlock多线程编程中,当代码需要同步时我们会用到锁。Java为我们提供了内置锁(synchronized)和显式锁(ReentrantLock)两种同步方式。显式锁是JDK1.5引入的,这两种
2023-05-30

编程热搜

目录