当前位置: 首页 > 后端技术 > Java

MySQL的锁那么多,不知从何说起,就看这篇文章吧

时间:2023-04-01 22:11:20 Java

MySQL有两个核心知识点,索引和锁。前面几篇文章已经详细讲解了MySQL索引的实现机制,今天我们就一起来了解一下MySQL锁。1为什么要锁?当多个事务并发操作同一批数据时,如果不加锁,则无法保证事务的隔离性,造成数据混乱。加锁是为了保证并发操作下数据的正确性。2锁的分类有哪些?按照锁的粒度可以分为:表锁、页锁、行锁、记录锁、间隙锁、邻键锁。根据锁的属性可以分为:共享锁和排它锁。根据加锁机制可以分为:乐观锁,悲观锁下面依次介绍这几种锁:表锁:MyISAM和InnoDB引擎都支持表锁。优点:开销小,加锁速度快,不会死锁。缺点:锁力强,锁冲突概率高,并发度最低。加锁方法:#给用户表加读锁locktableuserread;#同时给user表加上读锁和给order表tablesuserread,orderwrite加上写锁;什么情况下需要使用表锁?当需要更新表中大部分数据的事务涉及多张表,业务逻辑复杂时,加表锁可以避免死锁。页锁:优点:开销和加锁速度介于表锁和行锁之间。缺点:会出现死锁,锁定粒度介于表锁和行锁之间,并发度一般。目前只有BDB引擎支持页锁,应用场景很少。行锁:只有InnoDB引擎支持行锁,在索引上加锁。优点:开销大,加锁慢;会发生死锁。缺点:加锁粒度小,锁冲突概率低,并发度高。另外记录锁、间隙锁、键锁都是行锁。记录锁(RecordLocks):即锁定一条记录。#锁定id=1的用户updateusersetage=age+1whereid=1;间隙锁(GapLocks):即锁定一定范围,但不包含该范围的关键数据。#锁定id大于1小于10的用户updateusersetage=age+1whereid>1andid<10;上述SQL的锁定范围是(1,10)。Next-KeyLocks:由记录锁和间隙锁组成,既包括记录本身,也包括范围,左开右闭区间。#锁定id大于1小于等于10的用户updateusersetage=age+1whereid>1andid<=10;共享锁(又称读锁、S锁):作用:防止其他事务修改当前数据。加锁方式:在select语句末尾加上关键字lockinsharemode。#给id=1的用户加读锁select*fromuserwhereid=1lockinsharemode;独占锁(又名写锁,X锁):作用:防止其他事务读取或更新当前数据。锁定方法:在select语句末尾加上关键字forupdate。#给id=1的用户加写锁select*fromuserwhereid=1forupdate;乐观锁:一直假设别人不会修改当前数据,所以不会每次读取数据都加锁,只是在更新数据的时候,用版本判断别人是否修改了数据。Java原子包下的类是使用乐观锁(CAS)实现的。适用于读多写少的场景。锁定方式:读取版本selectid,name,age,versionfromuserid=1;更新数据判断版本是否被修改。更新用户集age=age+1whereid=1andversion=1;悲观锁:总是假设别人会修改当前数据,所以每次读取时,总是加锁。适用于写多读少的场景。加锁方式:#添加读锁select*fromuserwhereid=1lockinsharemode;#添加写锁select*fromuserwhereid=1forupdate;本文知识点总结:文章持续更新中,可微信搜索“一光架构”第一时间阅读更多技术干货。