mysql锁相关知识
按操作分类:
共享锁:
也叫读锁。针对同一数据,多个事务读取操作可以同时加锁互不影响,但是不能修改数据。
innodb 共享锁:
sql+ lock in share mode;例 select * from student lock in share mode;
当开启共享锁的时候,当前事务可以查询数据、修改数据,并且可以更换锁的类型;其他事务可以对该行进行共享锁查询,但是不能加排他锁查询,也不能修改数据。
myisam 读锁:
加锁:lock table 表名 read;解锁:unlock tables;
可以多个会话同时对一个表添加读锁,但是不能修改数据以及添加写锁。同一个会话添加读锁后也不能修改当前表的数据,
排他锁:
也叫做写锁。当前操作没完成时,会阻断其他操作的加锁读取和修改数据。
innodb 排他锁:
sql+for update 例 select * from student for update;
当开启排他锁时,当前事务可以查找数据和修改数据,也可以修改锁的类型,但是即便从排他锁变成共享锁,其他事务也不能加锁查询,本质上还是排他锁,其他事务只能查询数据,不能加锁也不能修改数据。
myisam 写锁:
lock table 表名 write ;解锁:unlock tables;
当前会话可以查询和修改数据,其他会话不能查询和修改数据
按粒度分类:
表级锁:
锁住整个表,开销小,加锁快,锁粒度大,发生锁冲突概率高,并发力度低,不会出现死锁现象。
myisam存储引擎支持的就是表锁,innodb存储引擎也支持表锁,但是默认的是行锁
行级锁:
锁住当前行,开销大,加锁慢,锁粒度小,发生锁冲突概率低,并发度高,会出现死锁现象。
innodb存储引擎默认支持行锁,但是需要用索引当作检索条件才能施加行锁(命中数据增加行锁,如果不命中数据则增加间隙锁(RR隔离级别)),否则会从行锁升级为表锁(RR级别会升级成表锁,RC级别不会,因为在RR级别上要保证可重复读,所以在遍历扫描数据的时候,为了防止扫描过的数据被其他数据修改或间隙被插入数据,从而导致数据不一致,索引mysql就把所有扫描过的数据和间隙都加上锁)
意向锁:
意向锁主要是针对表锁的,主要是为了提高加表锁的效率,是mysql自己加的锁,当事务给表的数据行加了共享锁或者排他锁的时候,同时会给表设置一个表示,代表这张表已经加了行锁,其他事务想要加表锁的时候,就不必要逐行判断有没有行锁可能对表锁造成冲突,直接读取这个标记就知道该不该枷锁,而这个标记就是意向锁
按照使用方式:
悲观锁:
对数据被外界修改保持保守状态,认为数据随时会被修改,整个数据处理过程中需要将数据加锁,悲观锁一般都是依靠关系型数据库提供的锁机制,我们之前学过的锁(共享锁,排他锁,读锁,写锁)都是悲观锁;用于写多读少
乐观锁:
每次自己操作数据的时候认为没有人会修改他,所以不去加锁,但是在更新的时候去判断再次期间数据有没有被修改,需要用户自己去实现,不会发生抢占资源,只有在提交操作的时候检查是否违反数据完整性;用于读多写少
方式:给数据表添加一个version列,每次 更新后都将这个列的值加一,读取数据时,将版本号取出来,在执行更新的时候,比较版本号,如果相同则执行,如果不相同说明这条数据已经发生变化了,用户自行根据这个通知来决定怎么处理,比如重新更新一次或者放弃更新。
事务与锁状态信息查看
-- 查看事务时间超过60秒的事务
select * from INFORMATION_SCHEMA.INNODB_TRX WHERE TIMESTAMPDIFF(SECOND ,trx_started,NOW()) > '60';
-- 查看锁
select * from INFORMATION_SCHEMA.INNODB_LOCKS;
-- 查看锁等待
select * from INFORMATION_SCHEMA.INNODB_LOCK_WAITS;
-- 释放锁,trx_mysql_thread_id可以从INNODB_TRX表里查看到
kill trx_mysql_thread_id;
-- 查看最近一次死锁信息
show engine innodb status;
大事务的影响
1、并发情况下,容易造成数据库连接池被撑爆
2、锁定的数据过多,容易造成大量阻塞和锁超时
3、执行时间长,容易造成主从延迟
4、回滚所需要的时间比较长
5、undo log 膨胀
6、容易导致死锁
事务优化实践原则
1、对于RC事务级别,可以将查询等数据准备操作放到事务外进行
2、事务中避免进行远程调用,远程调用要设置超时时间,防止事务等待太久
3、一次事务避免处理太多数据,可以拆分成多个事务分次处理
4、更新等涉及加锁的操作尽可能放在事务靠后的位置(因为更新操作是已经存在的数据,有可能其他事务还会使用这条记录,那么会造成等待)
5、能异步处理的尽可能异步处理
6、对于简单的业务,应用业务代码来保证数据准确性,不通过事务
网友评论