Я постараюсь кратко описать, что я должен понять, цель этого вопроса.
У меня есть большое многопоточное приложение, разработанное на Java. Каждый поток имеет жесткую логику для загрузки, проверки и анализа файла, а затем вставки этих данных в базу данных. Этап вставки / обновления базы данных тоже в потоке. Каждый поток выполняет несколько хранимых процедур, которые обновляют одну таблицу. Эти хранимые процедуры являются несколькими для каждого потока.
Эта база данных одновременно используется веб-приложением. Итак, как вы поняли, у меня проблема с тупиком. Я перепробовал все модели замков, но ни одна из них мне не помогла. В некоторые сроки SELECT from web работает долгое время.
Какой у меня вопрос в конце концов. Есть механизм / средства postgres для синхронизации хранимой процедуры или запроса? Я знаю, что это должно быть сделано с помощью модели замка, но у меня не было успеха. В качестве решения для MS Server я использую «WITH NOLOCK» для операторов SELECT. Я могу решить эту проблему с помощью синхронизации кода, но это действительно сложная логика.
По запросу выкладываю пример медленного запроса в процессе обновления.
SELECT c.id AS id,cn.name as name,c.parent_category_id AS parent_category_id,
CASE WHEN EXISTS (
SELECT p.id FROM category AS subcat
INNER JOIN product AS p ON subcat.id = p.category_id
WHERE subcat.parent_category_id=c.id LIMIT 1)
THEN true ELSE false END AS autoupdate
FROM category AS c
INNER JOIN category_name AS cn ON c.id=cn.category_id
LEFT JOIN category AS subcat ON subcat.parent_category_id = c.id
WHERE c.parent_category_id=0AND cn.langid=1 AND c.id != 1
AND EXISTS
(SELECT p.id FROM product AS p
WHERE p.category_id = c.id OR p.category_id = subcat.id LIMIT 1)
GROUP BY c.sort,c.id,cn.name,c.parent_category_id
ORDER BY c.sort, cn.name`
И объясните:
'Group (cost=947.74..987.96 rows=15 width=40)'
' -> Sort (cost=947.74..947.75 rows=15 width=40)'
' Sort Key: c.sort, cn.name, c.id, c.parent_category_id'
' -> Merge Left Join (cost=125.84..947.62 rows=15 width=40)'
' Merge Cond: (c.id = subcat.parent_category_id)'
' Filter: (SubPlan 2)'
' -> Sort (cost=64.46..64.46 rows=3 width=40)'
' Sort Key: c.id'
' -> Nested Loop (cost=0.00..64.45 rows=3 width=40)'
' -> Seq Scan on category c (cost=0.00..41.69 rows=3 width=18)'
' Filter: ((id 1) AND (parent_category_id = 0))'
' -> Index Scan using category_name_category_id_langid on category_name cn (cost=0.00..7.56 rows=1 width=30)'
' Index Cond: ((cn.category_id = c.id) AND (cn.langid = 1))'
' -> Sort (cost=61.38..62.46 rows=1084 width=16)'
' Sort Key: subcat.parent_category_id'
' -> Seq Scan on category subcat (cost=0.00..39.52 rows=1084 width=16)'
' SubPlan 2'
' -> Limit (cost=0.00..27.29 rows=1 width=8)'
' -> Seq Scan on product p (cost=0.00..36459.98 rows=1336 width=8)'
' Filter: ((category_id = $0) OR (category_id = $1))'
' SubPlan 1'
' -> Limit (cost=0.00..2.68 rows=1 width=8)'
' -> Nested Loop (cost=0.00..17889.28 rows=6684 width=8)'
' -> Seq Scan on category subcat (cost=0.00..40.60 rows=10 width=8)'
' Filter: (parent_category_id = $0)'
' -> Index Scan using product_category_id on product p (cost=0.00..1764.16 rows=668 width=16)'
' Index Cond: (p.category_id = subcat.id)'
Спасибо!
С наилучшими пожеланиями
Артем