MySQL有两个外围的知识点,索引和锁。前几篇文章曾经具体解说了MySQL索引实现机制,明天再一起学习一下MySQL的锁。
1 为什么要加锁?
当多个事务并发操作同一批数据的时候,如果不加锁,就无奈保障事务的隔离性,最初导致数据错乱。
加锁是为了保障并发操作下数据的正确性。
2 锁的分类有哪些?
按锁的粒度可分为:表锁、页面锁、行锁、记录锁、间隙锁、临键锁
按锁的属性可分为:共享锁、排它锁
按加锁机制可分为:乐观锁、乐观锁
上面顺次介绍一下这几种锁:
表锁:
MyISAM和InnoDB引擎均反对表锁。
长处:开销小,加锁快,不会呈现死锁。
毛病:锁定力度大,产生锁抵触概率高,并发度最低。
加锁形式:
# 对user表加读锁lock table user read;# 同时对user表加读锁,对order表加写锁lock tables user read, order write;
什么状况下须要用到表锁?
当须要更新表中的大部分数据
事务波及到多张表,业务逻辑简单,加表锁能够防止死锁。
页面锁:
长处:开销和加锁速度介于表锁和行锁之间。
毛病:会呈现死锁,锁定粒度介于表锁和行锁之间,并发度个别。
目前只有BDB引擎反对页面锁,利用场景较少。
行锁:
只有InnoDB引擎反对行锁,另外锁是加在索引下面的。
长处: 开销大,加锁慢;会呈现死锁。
毛病:锁定粒度小,产生锁抵触的概率低,并发度高。
另外记录锁、间隙锁、临键锁均属于行锁。
记录锁(Record Locks):
即对某条记录加锁。
# 对id=1的用户加锁update user set age=age+1 where id=1;
间隙锁(Gap Locks):
即对某个范畴加锁,然而不蕴含范畴的临界数据。
# 对id大于1并且小于10的用户加锁update user set age=age+1 where id>1 and id<10;
下面SQL的加锁范畴是(1,10)。
临键锁(Next-Key Locks):
由记录锁和间隙锁组成,既蕴含记录自身又蕴含范畴,左开右闭区间。
# 对id大于1并且小于等于10的用户加锁update user set age=age+1 where id>1 and id<=10;
共享锁(又称读锁、S锁):
作用:避免其余事务批改以后数据。
加锁形式:
在select语句开端加上lock in share mode关键字。
# 对id=1的用户加读锁select * from user where id=1 lock in share mode;
排他锁(又称写锁、X锁):
作用:避免其余事务读取或者更新以后数据。
加锁形式:
在select语句开端加上for update关键字。
# 对id=1的用户加写锁select * from user where id=1 for update;
乐观锁:
总是假如他人不会批改以后数据,所以每次读取数据的时候都不会加锁,只是在更新数据的时候通过version判断他人是否批改过数据,Java的atomic包下的类就是应用乐观锁(CAS)实现的。
实用于读多写少的场景。
加锁形式:
1.读取version
select id,name,age,version from user id=1;
2.更新数据,判断version是否批改过。
update user set age=age+1 where id=1 and version=1;
乐观锁:
总是假如他人会批改以后数据,所以每次读取的时候,总是加锁。
实用于写多读少的场景。
加锁形式:
# 加读锁select * from user where id=1 lock in share mode;# 加写锁select * from user where id=1 for update;
本文知识点总结:
以上就是全部内容,心愿对大家有所帮忙学习