存储过程不是并发的

时间:2015-02-04 11:28:07

标签: postgresql stored-procedures deadlock

我希望这个存储过程能够同时工作,但正如我在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;

1 个答案:

答案 0 :(得分:0)

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

两者都可能存在问题,但就互锁问题而言,UPDATE往往更成问题。

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

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

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