我的源表叫做 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
(或者更确切地说是其中的一行(被锁定。