mysql的表锁是作用于整个表的锁机制,用于限制多个会话同时对同一张表进行读写操作,在需要保证整表操作原子性或者避免大量行锁开销的场景下会经常用到。不同的存储引擎对表锁的支持程度不同,其中MyISAM引擎默认就会使用表锁,而InnoDB引擎也支持手动添加表锁,同时还有更细粒度的行锁机制。

mysql表锁的基本语法
mysql中手动操作表锁主要使用LOCK TABLES和UNLOCK TABLES两个语句,基本语法格式如下:
加表锁语法
加表锁时可以指定锁的类型,常见的类型有读锁和写锁:
-- 给表添加读锁,当前会话和其他会话都只能读表,当前会话不能写表,其他会话写表会阻塞 LOCK TABLES 表名 READ; -- 给表添加写锁,当前会话可以读写表,其他会话读写表都会阻塞 LOCK TABLES 表名 WRITE; -- 同时给多个表加锁,不同表可以指定不同的锁类型 LOCK TABLES 表1 READ, 表2 WRITE;
解锁语法
当不需要锁的时候,可以手动释放所有表的锁,也可以等待会话结束自动释放:
-- 释放当前会话所有加过的表锁 UNLOCK TABLES;
不同存储引擎的表锁特性
MyISAM引擎的表锁
MyISAM引擎的表锁是默认机制,执行查询语句时会自动给涉及的表加读锁,执行更新操作时会自动加写锁,不需要手动操作。读锁之间不会互相阻塞,但是读锁和写锁、写锁之间会互相阻塞,并发性能相对较低,适合读多写少的场景。
InnoDB引擎的表锁
InnoDB引擎默认使用行锁,只有在明确使用LOCK TABLES语句时才会加表锁,同时InnoDB的表锁和事务有交互,如果在事务中执行LOCK TABLES,会隐式提交当前事务,而且UNLOCK TABLES也会隐式提交事务,因此一般不建议在InnoDB中使用表锁,优先使用行锁提升并发性能。
使用示例
下面以一张用户信息表user_info为例,演示表锁的使用过程:
-- 会话1:给用户表加写锁 LOCK TABLES user_info WRITE; -- 会话1:可以正常查询和修改表数据 SELECT * FROM user_info WHERE id = 1; UPDATE user_info SET name = '张三' WHERE id = 1; -- 此时会话2执行查询会阻塞,直到会话1释放锁 -- SELECT * FROM user_info WHERE id = 1; -- 会话1:释放表锁 UNLOCK TABLES;
使用注意事项
- 加表锁后,当前会话只能访问被加锁的表,访问其他未加锁的表会报错,如果需要访问多个表,需要在加锁时把所有相关表都加锁。
- 表锁的粒度比较大,会阻塞其他会话的相关操作,不适合高并发的写场景,尽量只在必要的时候使用。
- 使用
LOCK TABLES加锁后,如果会话断开,锁会自动释放,不需要手动执行解锁语句。 - InnoDB引擎下,如果开启了自动提交,执行
LOCK TABLES会直接提交当前事务,需要注意事务的完整性。
表锁和行锁的选择
如果是MyISAM引擎,只能使用表锁;如果是InnoDB引擎,优先选择行锁,只有在需要批量操作整表、且确定行锁开销更大的场景下,才考虑使用表锁。行锁的粒度更小,并发性能更好,能够支持更多会话同时操作表中不同的行,而表锁会让整张表的操作串行化,降低并发能力。
mysql表锁lock_tablesunlock_tablesinnodb修改时间:2026-07-16 18:27:14