postgresql - PostgreSQL上的内存全行锁定问题
问题描述
指这个问题Concurrency Postgresql UPDATE
我尝试了锁定行,行锁定有另一个问题。有很多事务(我正在使用数据库主、虚拟和备份的 3 个节点以及应用程序的 6 个节点命中数据库)我尝试使用行锁运行 3 小时,之后数据库内存已满并且许多事务命中数据库失败。你有什么建议吗?
实际流量:
我正在使用 java 来处理这个,hibernate 和 PostgreSQL 用于数据库。我有表关系:
- 帐户
- 租户
- 发票
- 发票项目
- 平衡
帐户活动余额全部存储在表 invoice_items 中,对于 1 张发票有一些项目并存储在 invoice_items 中。当帐户例如帐户 A 进行充值时,它将生成数据插入到表中:
- 发票
- 发票项目
数据将是:
发票:id、account_id、invoice_date、created_date、created_by
表格发票
id | account_id | invoice_date | created_date | created_by
b0a9e664-186b-4b1a-9b43-9edef238765f e0802b10-70cd-4466-aa53-da1618749809 2019-10-08 2018-10-03 04:10:44.000000 Admin
invoice_items:id、类型、invoice_id、金额、account_id、created_date、created_by、current_balance、tenant_record_id
表 invoice_items
id | type | invoice_id | account_id | created_date | created_by | amount | current_balance | tenant
b0a9e664-186b-4b1a-9b43-9edef238765f CBA_ADJ b0a9e664-186b-4b1a-9b43-9edef238765f e0802b10-70cd-4466-aa53-da1618749809 2018-10-03 04:10:44.000000 Admin 1000 1000 1
faef610a-b8bc-4793-8a9e-f9f760e7ee6c CREDIT_ADJ b0a9e664-186b-4b1a-9b43-9edef238765f e0802b10-70cd-4466-aa53-da1618749809 2018-10-03 04:10:44.000000 Admin -1000 1000 1
1eaff7c3-226a-42c2-be1c-2939d5b72a60 CBA_ADJ ab77a359-42ce-4878-bb77-8e66e4227a4d e0802b10-70cd-4466-aa53-da1618749809 2018-10-03 05:22:43.000000 Admin 1 999 1
0a73af7f-3310-444c-b852-e5b3931fbbb6 USAGE ab77a359-42ce-4878-bb77-8e66e4227a4d e0802b10-70cd-4466-aa53-da1618749809 2018-10-03 05:22:43.000000 Admin -1 999 1
7bfc627e-01a3-4a5c-9531-deec9d526c54 CBA_ADJ a9fe1419-1aa1-4d4b-9af5-a62c4b44ed1c e0802b10-70cd-4466-aa53-da1618749809 2018-10-03 06:24:43.000000 Admin 1 998 1
bd3d7241-e18a-443e-a8d0-0dd74af51e27 USAGE a9fe1419-1aa1-4d4b-9af5-a62c4b44ed1c e0802b10-70cd-4466-aa53-da1618749809 2018-10-03 06:24:43.000000 Admin -1 998 1
因为我无法通过应用程序处理当前余额,所以我尝试使用触发器处理,当插入新记录时执行插入表余额的过程:
CREATE OR REPLACE FUNCTION public.function_insert_currentbalance()
RETURNS trigger
LANGUAGE plpgsql
AS $function$
BEGIN
PERFORM 1 FROM invoice_items
WHERE type = NEW.type and external_key = new.external_key
ORDER BY created_date, id DESC LIMIT 1
FOR UPDATE OF invoice_items;
IF new.type = 'CBA_ADJ' THEN
insert into balance (invoice_id, balance, invoice_items_id)
values (new.invoice_id, (SELECT SUM(amount) FROM invoice_items WHERE account_id= new.account_id and type=new.type), new.invoice_id);
END IF;
return null;
END;
$function$
;
对于数据插入具有类型为几行时的类型:
CBA_ADJ 和 USAGE -> 是交易类型
CBA_ADJ 和 CREDIT_ADJ 是 toupup 的类型
应用的类型是贷记和借记,要获得当前余额,只需计算属于 account_id 的金额的总和,以及类型为“CBA_ADJ”的表 invoice_items 中的租户。查询:
IF new.type = 'CBA_ADJ' THEN
insert into balance (invoice_id, balance, invoice_items_id)
values (new.invoice_id, (SELECT SUM(amount) FROM invoice_items WHERE account_id= new.account_id and type=new.type), new.invoice_id);
END IF;
解决方案
推荐阅读
- svg - 可以允许 SVG 元素溢出其掩码吗?
- php - 如何在处理雄辩关系的同时合并/合并三个具有精确模式但数据不同的数据库表?
- api - 如何验证 OAuth2 + PCKE 流的访问令牌
- amazon-web-services - 是否可以在私有 EC2 实例前向世界开放公共 API 网关?
- c# - 将实例方法作为参数传递,无需实例
- php - 雄辩的关系集合不会由属性访问器返回,但如果我使用关系()-> get();
- angular - Angular:延迟加载模块仅适用于开发(environment.production === false)
- ansible - Ansible - 只有最后一个 with_items 在文件中更新
- python - PyCharm 中是否有类似于 RStudio 的全局环境和部分代码执行的功能?
- listview - 如何将多行和多列绑定到列表视图?