为什么 postgres 在插入另一个表时会锁定一个表



我的源表叫做 Event 位于不同的数据库中,它有数百万行。每个事件都可以具有"删除"、"更新"或"新建"操作。

我们有一个Java进程,它按照这些事件的创建顺序经历这些事件,并执行各种规则,然后将结果插入到多个表中以进行查找,分析等。

我现在正在使用 JdbcTemplate 并使用 batchUpdate 按顺序删除和更新插入到 Postgres DB,但我也希望能够并行。每批是 1,000 个要插入/更新插入或删除的实体。

但是,目前甚至以顺序方式进行,Postgres 也会以某种方式锁定查询,我对此知之

甚少,为什么。以下是一些代码

entityService.deleteBatch(deletedEntities);
indexingService.deleteBatch(deletedEntities);
...
entityService.updateBatch(allActiveEntities);
indexingService.updateBatch(....);

这些服务中的每一个都在不同的表中插入/删除。不过,它们在一个事务中。

以下查询

SELECT
activity.pid,
activity.usename,
activity.query,
blocking.pid AS blocking_id,
blocking.query AS blocking_query
FROM pg_stat_activity AS activity
JOIN pg_stat_activity AS blocking ON blocking.pid = ANY(pg_blocking_pids(activity.pid));

返回

Query being blocked: "insert INTO ENTITY (reference, seq, data) VALUES($1, $2, $3) ON CONFLICT ON CONSTRAINT ENTITY_c DO UPDATE SET data = $4",
Blockking query: delete from ENTITY_INDEX where reference = $1 

这些表之间没有外部约束。而且我们确实有索引,因此我们可以在流程中运行查询来处理。

为什么一个完全不同的表可以阻止其他表?我们如何解决这个问题?

您的查询具有误导性。

它显示为"阻塞查询"实际上是在阻塞事务中运行的最后一个语句。

可能是同一事务中的先前语句导致entity(或者更确切地说是其中的一行(被锁定。

最新更新