锁的粒度:
1.整个mysql 的server 级别
2.这个表的 table 级别
3.表中以行为单位的row 级别.
其中,MyISAM 引擎只有 server 和table 级别.Innodb 还支持row 级别.
锁有 read和write 这两种类型.
还有特别的 table 级别的read local 类型.
对myisam 来说:
1.read 锁
1.1 会导致加锁的session 只能执行查询操作,更新操作会报错.
1.2 同时也不能对未加锁的表进行查询和更新操作.
1.3 而其他未加锁的session 可以查询,更新操作会被阻塞.
2.write 锁
2.1 加锁的session 可以查询和更新.
2.3 同时也不能对未加锁的表进行查询和更新操作.
2.2 未加锁的session 的查询和更新操作会阻塞
3.read local
和read 一样,除了:
3.1 加锁的session 更新报错,而未加锁的session 却可以执行插入操作,不过新记录必须插入到表的末尾.
对Innodb来说
1.read 锁:
行粒度的锁的实现:
select * from 表 where 条件语句 lock in share mode
1.1 加锁的session,可以查询和更新所有行.
1.2 未加锁的session 可以查询所有行和对没有加锁的行更新.
1.3 未加锁的session 对更新则阻塞.
1.4 未加锁的session 新添加读锁的查询操作可以执行(即可以再添加读锁)
2.write 锁
行粒度的锁的实现:
select * from 表 where 条件语句 for update
insert/update/delete 语句 //自动添加行级锁
2.1 加锁的session,可以查询和更新所有行.
2.2 未加锁的session 可以查询所有行和对没有加锁的行更新.
2.3 未加锁的session 对更新则阻塞.
2.4 未加锁的session 新添加读锁的查询操作被阻塞(即不能再添加读锁)
3.其他注意点:
3.1 锁的生命周期是语句执行的周期.不过可以使用start transaction 开启事务来延长生命周期,事务周期就是锁的存在时间.
3.2 innodb 的行锁是通过索引来实现的.
如 :一个查询/更新不是通过索引来查找,那么行级锁会自动升级为表级锁.
4.行级锁和表级锁
在Innodb 的引擎中,对表添加行级锁的时候会自动添加一个相同类型的意向锁.这个锁不会影响行级锁之间的操作,只会在这个表添加表级锁的时候才会有影响.
所以这个意向锁的作用在于 表示这个表存在行级锁.以便在添加表级锁的时候产生相互作用.
4.1 在存在read 行级锁的时候:
4.1.1 原来的read 行级锁session 不受影响
4.1.2 未有锁的sessoin可以添加表级别read 锁.
4.1.3 添加表级write 锁时阻塞.
4.2 存在write 行级锁的时候:
4.2.1 原来的write 行级锁session 不受影响
4.2.2 未有锁的session 添加表级read 锁和write 锁都会被阻塞.