我正在尝试找出导致我的应用程序出现问题的原因。问题的要点是postgres服务器日志在upsert查询中显示死锁,我不确定为什么会发生这种情况-我没有将upsert包裹在事务中,并且我的ups不超过一次1行。
我的表的结构如下:
postgres=> \d test_data_table
Table "public.test_data_table"
Column | Type | Collation | Nullable | Default
--------+-------+-----------+----------+---------
id | text | | not null |
data | jsonb | | |
Indexes:
"test_data_table_pkey" PRIMARY KEY, btree (id)
和正在运行的upsert查询是这样的:
INSERT INTO test_data_table (id, data)
VALUES ($1, to_jsonb($2::jsonb))
ON CONFLICT (id) DO
UPDATE SET id = $3, data = to_jsonb($4::jsonb);
我将问题简化为两个Java线程,它们仅同时运行upsert查询(如果相关,请使用HikariCP + Postgres JDBC驱动程序)。通过在代码中放入打印语句,我可以看到只有一个线程能够正确完成升序。当我使用this Postgres wiki page中的“阻止和阻止活动的合并”(具体地说,是包含应用程序名称的“替代”版本)时,得到以下输出:
blocked_pid | blocked_user | blocking_pid | blocking_user | blocked_statement | current_statement_in_blocking_process | blocked_application | blocking_application
-------------+--------------+--------------+---------------+-------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+------------------------+------------------------
2576 | postgres | 2575 | postgres | INSERT INTO test_data_table (id, data)VALUES ($1, to_jsonb($2::jsonb)) ON CONFLICT (id) DO UPDATE SET id = $3, data = to_jsonb($4::jsonb) | INSERT INTO test_data_table (id, data)VALUES ($1, to_jsonb($2::jsonb)) ON CONFLICT (id) DO UPDATE SET id = $3, data = to_jsonb($4::jsonb) | PostgreSQL JDBC Driver | PostgreSQL JDBC Driver
(1 row)
在这一点上,我不确定可以采取什么措施有效地解决这个问题。
我已经看到: