基于湖库一体架构,统一管理结构化、半结构化与非结构化等多模态数据,一个系统承载事务处理、实时分析与 AI 工作负载。
LOCK TABLES
更新时间:2026-07-15 15:16:39
描述
该语句用于在会话(Session)中对表进行锁定,用于防止其他会话对同一表进行并发操作。当需要停止对某个表的所有 DML 和 DDL 操作时,可以使用该语句对表进行锁定。
前提条件
使用
LOCK TABLES语句前,需要打开如下租户级配置项:ALTER SYSTEM SET enable_lock_priority = TRUE;上述租户级配置项详细介绍,参见 enable_lock_priority。
注意
开启对应租户的
enable_lock_priority后,并不是所有节点都能立即感知到配置项。因此,需通过视图GV$OB_PARAMETERS查询所有节点上对应配置项的值,以保证租户下所有机器都生效。如果使用 proxy 连接集群,还需要打开 proxy 如下配置:
ALTER PROXYCONFIG SET proxy_id = 1; ALTER PROXYCONFIG SET client_session_id_version = 2; ALTER PROXYCONFIG SET enable_single_leader_node_routing = false;上述 proxy 配置详细介绍,参见 proxy_id、client_session_id_version 和 enable_single_leader_node_routing。
使用限制及注意事项
- 在打开表锁以后,不建议单独进行
RENAME TABLE,在RENAME TABLE前建议先获取写锁(WRITE)锁。 - 同 Session 上锁后,不支持读写上锁表,只允许
RENAME TABLE操作。 - 表别名(
alias)上锁和表原名上锁相同。 - 当前 Session 持有表锁时,再次执行
LOCK TABLES时,会上多个表锁。 START TRANSACTION不会解锁,必须通过UNLOCK TABLES或者 Session 断开后解除锁。LOCK TABLES不主动提交事务。- 不支持视图(View)上锁。
- 触发器/外键涉及的表中只对原表上锁。例如:在外键涉及的表中对子表上锁,父表不会上锁;对父表上锁,子表不会上锁。
LOCK TABLES语句的操作对象是临时表时,不上锁,不报错。
权限要求
执行 LOCK TABLES 语句,需要当前用户至少拥有对应对象的 LOCK TABLES 权限。更多有关 OceanBase 数据库权限的详细介绍,参见 MySQL 模式下的权限分类。
语法
LOCK {TABLE | TABLES}
tbl_name [[AS] alias] lock_type
[, tbl_name [[AS] alias] lock_type ...]
lock_type:
READ [LOCAL]
| [LOW_PRIORITY] WRITE
语法说明
| 字段名称 | 描述 |
|---|---|
| LOCK {TABLE | TABLES} | 表示对表或多个表进行锁定操作。LOCK TABLE 是 LOCK TABLES 的同义词。 |
| table_name | 指定要锁定表的名称。 |
| [AS] alias | 表示给表指定一个别名。 |
| lock_type | 指定表锁定的类型。有关表锁定类型的详细介绍可参见下文 lock_type。 |
lock_type
READ [LOCAL]:READ:表示所有的 Session 只能读取被锁的表,不能对该表进行修改(包括执行锁的 Session)。支持多个 Session 同时进行读取锁定操作。READ LOCAL:与READ表现相同。
[LOW_PRIORITY] WRITE:WRITE:表示对表进行写入锁定操作。当前版本WRITE不影响读。LOW_PRIORITY WRITE:与WRITE表现相同。
示例
创建示例表并插入测试数据。
创建表
orders。obclient> CREATE TABLE orders(order_id INT, customer_name VARCHAR(50), amount DECIMAL(10,2));向表
orders中插入测试数据。obclient> INSERT INTO orders VALUES(1, 'Alice', 1500.00);
打开租户级配置项
enable_lock_priority。obclient> ALTER SYSTEM SET enable_lock_priority = TRUE;执行如下语句,提交事务。
obclient> COMMIT;在会话 1 中执行如下语句,为
orders表设置读锁。obclient> LOCK TABLES orders READ;在会话 1 中执行如下语句,查看表
orders数据。obclient> SELECT * FROM orders;查询结果如下:
+----------+---------------+---------+ | order_id | customer_name | amount | +----------+---------------+---------+ | 1 | Alice | 1500.00 | +----------+---------------+---------+ 1 row in set在会话 1 中执行如下语句,向表
orders中插入一行数据。obclient> INSERT INTO orders VALUES(2, 'Bob', 2000.00);返回结果如下:
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction在会话 2 中执行如下语句,查看表
orders数据。obclient> SELECT * FROM orders;查询结果如下:
+----------+---------------+---------+ | order_id | customer_name | amount | +----------+---------------+---------+ | 1 | Alice | 1500.00 | +----------+---------------+---------+ 1 row in set在会话 2 中执行如下语句,向表
orders中插入一行数据。obclient> INSERT INTO orders VALUES(2, 'Bob', 2000.00);返回结果如下:
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction在会话 1 中执行如下语句,释放当前会话持有的所有表锁。
obclient> UNLOCK TABLES;在会话 1 中执行如下语句,向表
orders中插入一行数据。obclient> INSERT INTO orders VALUES(2, 'Bob', 2000.00);在会话 2 中执行如下语句,向表
orders中插入一行数据。obclient> INSERT INTO orders VALUES(3, 'Charlie', 2500.00);