从对数据操作的粒度来分:
从对数据操作的类型分:
mysql锁的特性大致归纳:
MyISAM在执行查询语句(SELECT)前会自动给涉及的所有表加读锁,在执行更新操作(UPDATE、DELETE、INSERT)前,会自动给涉及的表加写锁,这个过程并不需要用户干预,因此,用户一般不需要直接用 LOCK TABLE 命令给MyISAM表显式加锁。显式加锁语法:
lock table table_name read; lock table table_name write; unlock tables;
MyISAM表的读操作不会阻塞其他用户对同一表的读请求,但会阻塞对同一表的写操作 MyISAM表的写操作会阻塞其他用户对同一表的读和写操作 MyISAM的读写锁调度是优先写,这也是MyISAM不适合作写为主的表的存储引擎原因。因为写锁后,其他线程不能做任何操作,大量的更新会使查询很难得到锁,从而造成永远阻塞
查看锁争用情况:
show open tables; show status like 'Table_locks%';
加锁语句:
select * from table_name where … LOCK IN SHARE MODE select * from table_name where… FOR UPDATE
对于UPDATE、DELETE和INSERT语句,InnoDB会自动给涉及数据集加排它锁 对于普通SELECT语句,InnnoDB不会加任何锁
执行更新时,如果where条件没有索引 或 写法不当导致索引失效(例如:隐式转换),最终行锁变为表锁
-- name 类型为varchar(16) update test_innodb_lock set sex='2' where name = 400;
当我们用范围条件而不是使用相等条件检索数据,并请求共享或排它锁时,InnoDB会给符合条件的已有数据进行加锁;对于键值在条件范围内但不存在的记录,叫做“间隙(GAP)",InnoDB也会对这个”间隙“加锁,这种锁机制就是所谓的间隙锁(Next-Key锁)
update test_innodb_lock set sex = '0' where id < 4;
另一个事务如果执行下面语句时,会被阻塞
insert into test_innodb_lock values(2, '200', '1');
show status like 'innodb_row_lock%';
InnoDB存储引擎由于实现了行级锁定,虽然在锁定机制的实现方面带来了性能损耗可能比表锁会更高一些,但是在整体并发处理能力方面要远远优于MyISAM的表锁的。当系统并发量较高的时候,InnoDB的整体性能和MyISAM相比就会有比较明显的优势 但是,InnoDB的行级锁同样也有其脆弱的一面,当我们使用不当的时候,可能会让InnoDB的整体性能表现不仅不能比MyISAM高,甚至可能会更差
优化建议: