MYSQL关于锁的概述

共享锁(读锁)
共享锁指的就是对于多个不同的事务,对于一个资源共享同一个锁。对某一资源加共享锁,自身可可读该资源,其他人也可以读该资源(也可以再加共享锁,即共享锁共享多个内存),但无法修改。要想修改就必须等所有共享锁都释放完之后。语法:select * from table lock in share mode;。
比如:
窗口1,在一个未结束的事务中给一条数据加上共享锁。
BEGIN;
SELECT * FROM t_red_packet WHERE id = 1 LOCK IN SHARE MODE;
窗口2,给同一条数据加上共享锁,加锁成功。
SELECT * FROM t_red_packet WHERE id = 1 LOCK IN SHARE MODE;
窗口1和窗口2,更新该行数据,提示[Err] 1205 - Lock wait timeout exceeded; try restarting transaction。需要等到所有共享锁释放,才可以进行update操作。
UPDATE t_red_packet
SET user_id = 2
排它锁(写锁)
排它锁指的就是对于多个不同的事务,对同一个资源只能有一把锁。对某一资源加排它锁,自身可以进行增删改查,其他人无法进行加锁操作,更无法进行增删改操作。语法:select * from table for update。
窗口1,在一个未结束的事务中给一条数据加上排它锁。
BEGIN;
SELECT * FROM t_red_packet WHERE id = 1 FOR UPDATE;
窗口1,更新该行数据,成功。
UPDATE t_red_packet
SET user_id = 2
窗口2,查询该行数据,可以查询到。
SELECT * FROM t_red_packet WHERE id = 1
窗口2给该条数据加锁,提示[Err] 1205 - Lock wait timeout exceeded; try restarting transaction。
SELECT * FROM t_red_packet WHERE id = 1 FOR UPDATE;
共享锁(又称为读锁,简称S锁):事务对一数据开启共享锁,其他事务能访问到数据,但是只能读不能修改,只有本事务才能修改数据。
排他锁(又称为写锁,简称X锁):事务对一数据开启排他锁,当前事务没有提交前,会阻断其他事务的读锁和写锁,即不能再在同一数据上加锁。
行锁
行锁就是给一行数据进行加锁。
显式加锁:
上共享锁(读锁)的写法:lock in share mode,例如:
select math from zje where math>60 lock in share mode;
上排它锁(写锁)的写法:for update,例如:
select math from zje where math >60 for update;
表锁
表锁就是对一张表进行加锁。
扩展:间隙锁
当我们用范围条件而不是相等条件检索数据,并请求共享或排他锁时,InnoDB会给符合条件的已有数据记录的索引项加锁;对于键值在条件范围内并不存在的记录,叫做间隙

InnoDB也会对这个"间隙"加锁,这种锁机制就是所谓的间隙锁

– 用户A
update user set count=8 where id>2 and id<6
– 用户B;
update user set count=10 where id=5;
如果用户A在进行了上述操作后,事务还未提交,则B无法对2~6之间的记录进行更新或插入记录,会阻塞,当A将事务提交后,B的更新操作会执行。

优化建议
尽可能让所有数据检索都通过索引来完成,避免无索引行锁升级为表锁

合理设计索引,尽量缩小锁的范围

尽可能减少索引条件,避免间隙锁

尽量控制事务大小,减少锁定资源量和时间长度

尽可能低级别事务隔离

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值