MySQL什么时候触发表锁
- 修改表结构时
- 批量删除
insert into tab1 select * from tab2;
此时tab2
表会被锁住- 事务中需要更新大部分或者全部数据
- 事务涉及多个表时,可能会引起死锁,造成大量事务回滚
- 使用
select ...for update
查询语句时,此时分为以下几种情况:
以SELECT * from t_goods where ... for update;
为例:- 如果明确指定主键,并且有此数据,则触发行锁
- 如果明确指定主键,若查无此数据,无锁
- 如果无主键,则触发表锁
- 如果主键不明确(如:查询条件为
id > 23
时),则触发表锁 - 如果明确指定索引,并且有此数据,则触发行锁
- 如果明确指定索引,若查无此数据,无锁
- 具体表结构和命令见MySQL的SELECT ...for update
对于InnoDB表,在绝大部分情况下都应该使用行级锁,因为事务和行锁往往是我们之所以选择InnoDB表的理由。但在另一个特殊事务中,也可以考虑使用表级锁。
第一种情况是:事务需要更新大部分或全部数据,表又比较大,如果使用默认的行锁,不仅这个事务执行效率低,而且可能造成其他事务长时间锁等待和锁冲突,这种情况下可以考虑使用表锁来提高该事务的执行速度。
第二种情况是:事务涉及多个表,比较复杂,很可能引起死锁,造成大量事务回滚。这种情况也可以考虑一次性锁定事务涉及的表,从而避免死锁、减少数据库因事务回滚带来的开销。
当然,应用中这两种事务不能太多,否则,就应该考虑使用MyISAM表。
MySQL中的锁(表锁、行锁)
Reference:
评论区