存储过程不是并发的

Stored procedure is not concurrent

我希望此存储过程同时工作,但正如我在 PgAdmin 中看到的那样,它不能。一个进程被另一个进程阻塞(等他完成)。在我看来,更新查询并发 运行 没有问题。所以这都是关于 INSERT 的,对吗?我试图在更新查询上设置 ROW SHARE EXCLUSIVE LOCK,但我遇到了死锁。

    UPDATE product p SET category_id = m.internal_category_id, category_from=m.cat_prior FROM main_table m
    WHERE  p.mpn=m.mpn AND
    p.vendor_id = m.internal_vendor_id  AND
    m.new_prod=false and
    m.internal_category_id IS NOT NULL AND
    (category_from is null or category_from<=m.cat_prior);

    INSERT INTO product(vendor_id, category_id, mpn, name, category_from)
    SELECT DISTINCT ON(m.mpn, m.internal_vendor_id) m.internal_vendor_id, m.internal_category_id, m.mpn, m.prod_name, m.cat_prior
    FROM main_table m
    LEFT OUTER JOIN product ON product.mpn=m.mpn AND product.vendor_id=m.internal_vendor_id
    WHERE m.new_prod='1' AND m.internal_vendor_id IS NOT NULL
    AND product.mpn IS NULL;

    UPDATE main_table m SET internal_product_id = p.id
    FROM product p
    WHERE p.mpn=m.mpn AND p.vendor_id = m.internal_vendor_id ;

    UPDATE vendor SET has_products = true FROM (SELECT DISTINCT v.id as id FROM vendor v INNER JOIN product p ON p.vendor_id = v.id) AS r WHERE vendor.id = r.id;
    UPDATE vendor SET has_products = false FROM (SELECT DISTINCT v.id as id FROM vendor v LEFT JOIN product p ON p.vendor_id = v.id WHERE p.vendor_id IS NULL) AS r WHERE vendor.id = r.id;

在我看来,更新查询没有问题 运行 同时。所以这都是关于 INSERT 的,对吗?

两者都可能有问题,但 UPDATE 在互锁方面往往有更多问题。

当一个 UPDATE 修改一行而另一个 UPDATE 试图修改同一行时,第二个更新将等待第一个事务提交或回滚。

另一方面,当两个 INSERT 命中同一个 table 时,只有在 table 上有唯一索引并且两个语句都试图插入相同的索引值。这是不寻常的,因为除非第一个事务中止,否则会导致索引违规错误。

单看一段代码,很难知道并发调用是否会命中相同的行,这取决于数据。但是,在您的情况下,您的第一个 UPDATE 似乎没有采用任何参数有点可疑。