我会尽快描述一下我必须理解这个问题的目的。 我有用Java开发的大型多线程应用程序。每个线程都有硬逻辑来加载,验证和解析文件,然后将这些数据插入数据库。也在线程中插入/更新数据库的阶段。每个线程运行几个存储过程,更新一个表。这些存储过程是每个线程的几个。
此数据库同时由Web应用程序使用。所以你知道我遇到了死锁的问题。我尝试了所有的锁模型,但其中任何一个都没有帮助我。在某些时间段内,来自网络的SELECT工作时间很长。
毕竟我的问题是什么。有postgres机制/手段来同步存储过程或查询?我知道它必须通过锁模型来完成,但我没有成功。作为MS Server的解决方案,我对SELECT语句使用“WITH NOLOCK”。我可以通过代码同步来解决这个问题,但它确实很复杂。
根据要求,我在更新过程中发布慢查询的示例。
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)'
谢谢! 最好的祝福 阿尔乔姆
答案 0 :(得分:4)
我认为你要找的术语是“isolation level”。我想你的应用程序的某些部分可能会容忍脏读,不可重写的读取或幻像读取。但是在PostgreSQL的当前版本中,writers don't block readers, and readers don't block writers。
所以我的问题是:你如何知道延迟是由锁定引起的,而不是由磁盘I / O,连接负载,其他进程(与dbms无关的进程,如长时间运行)引起的cron job),还是别的什么?
答案 1 :(得分:2)
PostgreSQL中不需要“WITH NOLOCK”,因为读者永远不会被读者阻止。阻止表上的SELECT的唯一方法是使用独占访问来手动锁定表 - 这不是普通DML语句所做的事情。只有ALTER TABLE才能获得这样的锁定。
但我不确定我理解你的问题。
你已经遇到了死锁问题吗?或者你认为没有测试你会拥有它们吗?