2015-02-04 3 views
0

Я хочу, чтобы эта хранимая процедура работала одновременно, но, как я вижу в 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; 

ответ

0

Кажется мне, запрос на обновление не имеет никаких проблем с быть запущен одновременно. Так что это все о INSERT, я прав?

Оба могут быть проблематичными, но ОБНОВЛЕНИЕ имеет тенденцию быть более проблематичным в отношении блокировки.

Когда UPDATE изменяет строку, а другой UPDATE пытается изменить одну и ту же строку, вторая ставится на ожидание, пока первая транзакция не завершится или не вернется.

С другой стороны, когда два INSERT попадают в одну и ту же таблицу, второй из них должен ждать только в том случае, если в таблице есть уникальный индекс, и оба оператора пытаются вставить одно и то же индексированное значение. Это необычно, потому что это приведет к ошибке нарушения индекса, если первая транзакция не прерывается.

Просто взглянув на кусок кода, трудно понять, будут ли одновременные вызовы попадать в одни и те же строки или нет, это зависит от данных. Однако в вашем случае немного подозрительно, что ваш первый UPDATE, похоже, не принимает никаких параметров.