首页 > 其他 > 详细

共享锁(读锁)/排他锁(写锁)

时间:2021-08-16 22:42:19      阅读:23      评论:0      收藏:0      [点我收藏+]

读锁与写锁区别

语法

// 读锁
select ... lock in share mode
// 写锁
select ... for update

共同点

  1. 都是作用在 select 语句中
  2. A 事务对某 select 语句加锁之后(未提交事务),其他事务无法对该数据执行修改操作(update/delete)
  3. 只有当 A 事务提交或回滚,其他事务才能对数据进行修改操作(update/delete)
  4. 不管读锁还是写锁,它们都属于悲观锁的一种形式

不同点

  1. 读锁:当 A 事务对 select 语句加上读锁时,其他事务对 select 加上读锁获取数据不会阻塞
  2. 写锁:当 A 事务对 select 语句加上写锁时,其他事务对 select 加上读锁/写锁获取数据阻塞,只有等待 A 事务提交或回滚,其他事务才能读取到数据

读锁写锁示例

假设有张 user 表,表中数据如下
技术分享图片

读锁(共享锁)

------------------A事务------------------ ------------------B事务------------------
对 id = 1 的数据增加读锁,但是并不提交事务
技术分享图片
不加锁的查询,查询成功
技术分享图片
加上读锁查询,查询成功
技术分享图片
对 id = 2 的数据进行修改,修改成功
技术分享图片
对 id = 1 的数据进行修改,修改出现阻塞
技术分享图片
事务提交
技术分享图片
由于 A事务 commit 了,阻塞状态取消,修改成功
技术分享图片

写锁(排他锁)

------------------A事务------------------ ------------------B事务------------------
对 id = 1 的数据增加写锁,但是并不提交事务
技术分享图片
不加锁的查询,查询成功
技术分享图片
加上写锁查询 id = 2 的数据,查询成功
技术分享图片
加上写锁查询 id = 1 的数据,查询出现阻塞
技术分享图片
事务提交
技术分享图片
由于 A事务 commit 了,阻塞状态取消,查询成功
技术分享图片
对 id = 1 的数据增加写锁,但是并不提交事务
技术分享图片
修改 id = 2 的数据,修改成功
技术分享图片
修改 id = 1 的数据,修改出现阻塞
技术分享图片
事务提交
技术分享图片
由于 A事务 commit 了,阻塞状态取消,修改成功
技术分享图片

注意事项

注意注意注意:for update 仅适用于InnoDB,并且必须开启事务,在begin与commit之间才生效。或者在代码中使用@Transactional才能生效。

行锁:访问数据库的时候,锁定整个行数据,防止并发错误。 如InnoDB存储引擎使用行锁
表锁:访问数据库的时候,锁定整个表数据,防止并发错误。 如MyISAM存储引擎使用表锁

例1:明确指定主键,并且数据真实存在,行锁

select status from t_goods where id = 1 for update;

例2:明确指定主键,但数据不存在,无锁

select status from t_goods where id = 0 for update;

例3:主键不明确,表锁

select status from t_goods where id <= 3 for update;

例4:无主键,表锁

select status from t_goods for update;

共享锁(读锁)/排他锁(写锁)

原文:https://www.cnblogs.com/luchaoguan/p/15149120.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!