【mysql】mysql中的锁机制
一、分类
mysql的锁机制不同的存储引擎支持不同的锁机制,分为表级锁、行级锁、页面锁。myisam和memory存储引擎采用的是表级锁(table-level locking);bdb存储引擎采用的是页面锁(page-level locking),但也支持表级锁;innodb存储引擎既支持行级锁(row-level locking),也支持表级锁,但默认情况下是采用行级锁
表级锁:开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低。
行级锁:开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。
页面锁:开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之间,并发度一般
二、表级锁
mysql的表级锁有两种模式:表共享读锁(table read lock)和表独占写锁(table write lock)。
对myisam表的读操作,不会阻塞其他用户对同一表的读请求,但会阻塞对同一表的写请求;对 myisam表的写操作,则会阻塞其他用户对同一表的读和写操作。
myisam在执行查询语句(select)前,会自动给涉及的所有表加读锁,在执行更新操作 (update、delete、insert等)前,会自动给涉及的表加写锁,这个过程并不需要用户干预,因此,用户一般不需要直接用lock table命令给myisam表显式加锁。
三、行级锁
innodb与myisam的最大不同有两点:一是支持事务(transaction);二是采用了行级锁。
行级锁也支持读锁和写锁两类。
1、如何加锁?
mysql innodb引擎默认的修改数据语句:update,delete,insert都会自动给涉及到的数据加上排他锁,select语句默认不会加任何锁类型,如果加排他锁可以使用select …for update语句,加共享锁可以使用select … lock in share mode语句。所以加过排他锁的数据行在其他事务种是不能修改数据的,也不能通过for update和lock in share mode锁的方式查询数据,但可以直接通过select …from…查询数据,因为普通查询没有任何锁机制。
2、实现原理
innodb行锁是通过给索引上的索引项加锁来实现的,这一点mysql与oracle不同,后者是通过在数据块中对相应数据行加锁来实现的。innodb这种行锁实现特点意味着:只有通过索引条件检索数据,innodb才使用行级锁,否则,innodb将使用表锁!
3、间隙锁
当我们用范围条件检索数据或者使用相等条件请求给一个不存在的记录加锁,并请求共享或排他锁时,innodb会给符合条件的已有数据记录的 索引项加锁用范围条件检索数据
举例来说,假如表中只有5条记录,其empid的值分别是1、2、3、6、7
select * from emp where id > 6 for update; 锁定【6,无限大】区间 select * from emp where id=5 for update; 锁定【3,6】区间 select * from emp where id=3 for update; 锁定3这一行