PostgreSQL锁定问题

3

我试图找出如何在Postgres中锁定整个表以防止写入,但似乎并没有起作用,因此我认为我做错了什么。

例如,表名为“users”。

LOCK TABLE users IN EXCLUSIVE MODE;

当我检查pg_locks视图时,它似乎不在其中。我尝试了其他锁定模式,但都无济于事。

其他事务也能执行LOCK函数,并且不像我想象的那样被阻塞。

在psql工具(8.1)中,我只是得到了LOCK TABLE的返回结果。

任何帮助都将是美好的。


1
为什么你想要锁定这个表格? - undefined
3个回答

10

SQL标准中没有LOCK TABLE,而是使用SET TRANSACTION来指定事务的并发级别。您应该能够在像这样的事务中使用LOCK。

BEGIN WORK;
LOCK TABLE table_name IN ACCESS EXCLUSIVE MODE;
SELECT * FROM table_name WHERE id=10;
Update table_name SET field1=test WHERE id=10;
COMMIT WORK;

我实际在我的数据库上测试过这个。


1
请注意,access exclusive mode 不仅阻止其他进程对表进行写操作,还阻止其读取表的任何内容。您可以使用 share row exclusive mode 来专门锁定表,以防止其他进程对其进行更新或插入操作。 - undefined

5
请记住,“锁定表”仅持续到事务结束。因此,除非您已在psql中发出“begin”,否则它是无效的。
(在9.0中,这会产生一个错误:“LOCK TABLE只能在事务块中使用”。 8.1版本非常老旧)

0

锁定只在当前事务结束时生效,并在提交(或回滚)事务时释放。

因此,您需要将语句嵌入到 BEGINCOMMIT/ROLLBACK 块中。执行后:

BEGIN;
LOCK TABLE users IN EXCLUSIVE MODE;

您可以运行以下查询以查看当前在users表上活动的锁:

SELECT * FROM pg_locks pl LEFT JOIN pg_stat_activity psa ON pl.pid = psa.pid WHERE relation = 'users'::regclass::oid;

查询应该显示对users表的独占锁。在执行COMMIT并重新运行上述查询之后,该锁不应再存在。

此外,您还可以使用类似https://github.com/jnidzwetzki/pg-lock-tracer/的锁追踪工具来实时了解PostgreSQL服务器的锁定活动。使用这样的锁追踪工具,您可以实时查看哪些锁被获取和释放。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接