MySQL有两个核心的知识点,索引和锁。前几篇文章已经详细讲解了MySQL索引实现机制,今天再一起学习一下MySQL的锁。
当多个事务并发操作同一批数据的时候,如果不加锁,就无法保证事务的隔离性,最后导致数据错乱。
加锁是为了保证并发操作下数据的正确性。
下面依次介绍一下这几种锁:
MyISAM和InnoDB引擎均支持表锁。
加锁方式:
# 对user表加读锁
lock table user read;
# 同时对user表加读锁,对order表加写锁
lock tables user read, order write;
什么情况下需要用到表锁?
目前只有BDB引擎支持页面锁,应用场景较少。
只有InnoDB引擎支持行锁,另外锁是加在索引上面的。
另外记录锁、间隙锁、临键锁均属于行锁。
即对某条记录加锁。
# 对id=1的用户加锁
update user set age=age+1 where id=1;
即对某个范围加锁,但是不包含范围的临界数据。
# 对id大于1并且小于10的用户加锁
update user set age=age+1 where id>1 and id<10;
上面SQL的加锁范围是(1,10)。
由记录锁和间隙锁组成,既包含记录本身又包含范围,左开右闭区间。
# 对id大于1并且小于等于10的用户加锁
update user set age=age+1 where id>1 and id<=10;
作用:防止其他事务修改当前数据。
加锁方式:
在select语句末尾加上 lock in share mode 关键字。
# 对id=1的用户加读锁
select * from user where id=1 lock in share mode;
作用:防止其他事务读取或者更新当前数据。
加锁方式:
在select语句末尾加上 for update 关键字。
# 对id=1的用户加写锁
select * from user where id=1 for update;
总是假设别人不会修改当前数据,所以每次读取数据的时候都不会加锁,只是在更新数据的时候通过version判断别人是否修改过数据,Java的atomic包下的类就是使用乐观锁(CAS)实现的。
适用于读多写少的场景。
加锁方式:
总是假设别人会修改当前数据,所以每次读取的时候,总是加锁。
适用于写多读少的场景。
加锁方式:
# 加读锁
select * from user where id=1 lock in share mode;
# 加写锁
select * from user where id=1 for update;
作者:程序员斯纳Java
链接:https://www.zhihu.com/question/483748761/answer/2549141298
来源:知乎 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
本文系转载,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文系转载,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。