我知道SELECT
在Postgres中不需要行锁。因此,我可以在连接1中从某个表T
发出SELECT
,然后其他人可以在连接2中发出DELETE
(同一表T
中的所有行),并且DELETE
不会引起任何阻塞。对吧?
如下所示:
SELECT是否阻止返回的行被删除?
好吧…我的问题是:这种行为是否取决于两个连接中使用的ISOLATION LEVEL
?
我为什么要问这些?
在现实世界中,我们有一个类似的并发场景(如上所述),但SELECT
vs.TRUNCATE TABLE
。这里我们有一个阻塞问题,因为TRUNCATE TABLE
(不像DELETE * FROM TABLE
)需要排他表锁(在SELECT
运行时它无法获得)。因此,我们正在考虑使用DELETE *
而不是TRUNCATE
(尽管DELETE
有点慢)来解决这个阻塞问题。
- 这种方法有效吗?
- 行为是否取决于隔离级别?
无论您使用什么隔离级别(使用REPEATABLE READ
或更高级别,您当然可以获得序列化错误,但这是无关的),您的解决方案都将有效。
然而,TRUNCATE
将更有效。如果锁出现问题,则表明您有使用该表的长时间运行事务。尽量避免这种情况,因为长事务通常是有问题的。