首批通过分布式安全可靠测评,为关键业务系统打造
锁定查询结果 SELECT FOR UPDATE
更新时间:2026-03-21 12:54:30
OceanBase 数据库支持多版本并发控制 MVCC。默认情况下,读事务不会阻塞写事务的执行,但可以通过 SELECT ... FOR UPDATE 的方式为读事务的对象加锁,从而达到阻塞写事务的目的。
本文通过具体示例介绍如何使用 SELECT FOR UPDATE 锁定查询结果。
示例
使用 SELECT FOR UPDATE 锁定查询结果。
创建示例表并录入合适的数据。
执行下面 SQL 语句,创建
test_tbl1表。CREATE TABLE test_tbl1(id number, name VARCHAR(18), c_date date, PRIMARY KEY (id) );执行下面 SQL 语句,在
test_tbl1表中插入数据。INSERT INTO test_tbl1 VALUES(1,'A1',date'2019-09-09'), (2,'B1',date'2019-06-06'), (3,'C1',date'2019-05-05'), (4,'D1',date'2020-02-02'), (5,'F1',date'2021-01-01');执行下面 SQL 语句提交事务。
COMMIT;
在 会话 1 中,使用
FOR UPDATE语法在表test_tbl1中对id值等于1的记录进行查询并添加行锁,所有并发的更新都会被阻塞并等待。SELECT name,c_date FROM test_tbl1 WHERE id = 1 FOR UPDATE;返回结果如下:
+------+-----------+ | NAME | C_DATE | +------+-----------+ | A1 | 09-SEP-19 | +------+-----------+ 1 row in set在 会话 2 中,执行下面 SQL 语句在表
test_tbl1中id值等于1的行对应的name的改为A1A1。该 SQL 语句会等待,直到 会话 1 的事务ROLLBACK或者COMMIT才得到执行。UPDATE test_tbl1 SET name = 'A1A1' WHERE id = 1;返回结果如下:
OBE-30006: resource busy; acquire with WAIT timeout expired在 会话 1 中,执行下面 SQL 语句提交事务。
COMMIT;在 会话 2 中,再次执行 步骤 3 的更新语句。
UPDATE test_tbl1 SET name = 'A1A1' WHERE id = 1;返回结果如下:
Query OK, 1 row affected Rows matched: 1 Changed: 1 Warnings: 0在 会话 2 中,执行下面 SQL 语句提交事务。
COMMIT;在 会话 1 中查询更新后的数据。
SELECT name,c_date FROM test_tbl1 WHERE id = 1;返回结果如下:
+------+-----------+ | NAME | C_DATE | +------+-----------+ | A1A1 | 09-SEP-19 | +------+-----------+ 1 row in set