select for update

select …… for update 是一种分布式锁,为了在查询时,避免其他用户以该表进行增、删、改等操作,造成表的不一致性。一般不加数据库锁,比较重(太底层,影响广泛),可以使用分布式锁 / sychorized / Lock。

一、例子

  • select status from t_goods where id=1 for update;

此时在t_goods表中,id为1的那条数据就被我们锁定了,其它的事务必须等本次事务提交之后才能执行。这样我们可以保证当前的数据不会被其它事务修改。

注:1、与普通查询不一样的是,我们使用了select…for update的方式,这是通过数据库实现的一种悲观锁

2、需要注意的是,在事务中,只有SELECT ... FOR UPDATE 或LOCK IN SHARE MODE 相同数据时会等待其它事务结束后才执行,一般SELECT ... 则不受此影响。拿上面的实例来说,当我执行select status from t_goods where id=1 for update;后。我在另外的事务中如果再次执行select status from t_goods where id=1 for update;则第二个事务会一直等待第一个事务的提交,此时第二个查询处于阻塞的状态,但是如果我是在第二个事务中执行select status from t_goods where id=1;则能正常查询出数据,不会受第一个事务的影响。

 二、使用要求

存储引擎:仅适用于InnoDB引擎

加锁粒度:InnoDB默认是行级别的锁(当有明确指定的主键时候,是行级锁,否则是表级别)

走索引:InnoDB行锁是通过给索引上的索引项加锁来实现的,只有通过索引字段检索数据,InnoDB才使用行级锁,否则,InnoDB将使用表锁

事务:并且必须开启事务,在begin与commit之间才生效。

 三、几种句式

select * from t for update 会等待行锁释放之后,返回查询结果。
select * from t for update nowait 不等待行锁释放,提示锁冲突,不返回结果
select * from t for update wait 5 等待5秒,若行锁仍未释放,则提示锁冲突,不返回结果
select * from t for update skip locked 查询返回查询结果,但忽略有行锁的记录

 四、涉及的锁

悲观锁、乐观锁

悲观锁:每次使用都加锁。适合频繁写入的场景(会堵塞,读多的话效率低,所以写多更合适)

乐观锁:平时不加锁,需要再加锁 。适合频繁读取的场景(加锁少,所以读取效率高)

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

读锁:读的时候,其他人也可以读,不可以写

写锁:读的时候,其他人不可以读,不可以写

详细了解-select...from... for update

https://blog.csdn.net/ll594317566/article/details/103869619(select...for update使用方法)

posted @   zhegeMaw  阅读(86)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话
点击右上角即可分享
微信分享提示