我遇到了一个问题,我有一个功能,根据某些情况需要序列化访问.这似乎是使用咨询锁的好例子.但是,在相当繁重的负载下,我发现序列化访问没有发生,我看到并发访问该函数.
该功能的目的是为事件提供"库存控制".这意味着,它旨在限制特定事件的并发票购买,以使事件不被超卖.这些是应用程序/数据库中使用的唯一建议锁.
我发现偶尔会有比eventTicketMax值更多的门票.由于咨询锁定,这似乎不可能.在以低音量进行测试时(或在获取锁定后手动引入延迟,例如pg_sleep),事情按预期工作.
CREATE OR REPLACE FUNCTION createTicket(
userId int,
eventId int,
eventTicketMax int
) RETURNS integer AS $$
DECLARE insertedId int;
DECLARE numTickets int;
BEGIN
-- first get the event lock
PERFORM pg_advisory_lock(eventId);
-- make sure we aren't over ticket max
numTickets := (SELECT count(*) FROM api_ticket
WHERE event_id = eventId and status <> 'x');
IF numTickets >= eventTicketMax THEN
-- raise an exception if this puts us over the max
-- and bail
PERFORM pg_advisory_unlock(eventId);
RAISE EXCEPTION 'Maximum …
Run Code Online (Sandbox Code Playgroud) 我正在尝试确定以下查询是否存在"低成本"优化.我们已经实施了一个系统,"门票"可以获得"积分",因此可以进行排名.为了支持分析类型的查询,我们将每个票证的等级(票证可以绑定)与票证一起存储.
我发现,在规模上,更新此排名非常缓慢.我试图在一组大约20k门票的"门票"上运行下面的场景.
我希望有人可以帮助确定原因并提供一些帮助.
我们在postgres 9.3.6
这是一个简化的票证表架构:
ogs_1=> \d api_ticket
Table "public.api_ticket"
Column | Type | Modifiers
------------------------------+--------------------------+---------------------------------------------------------
id | integer | not null default nextval('api_ticket_id_seq'::regclass)
status | character varying(3) | not null
points_earned | integer | not null
rank | integer | not null
event_id | integer | not null
user_id | integer | not null
Indexes:
"api_ticket_pkey" PRIMARY KEY, btree (id)
"api_ticket_4437cfac" btree (event_id)
"api_ticket_e8701ad4" btree (user_id)
"api_ticket_points_earned_idx" btree (points_earned)
"api_ticket_rank_idx" btree ("rank")
Foreign-key constraints:
"api_ticket_event_id_598c97289edc0e3e_fk_api_event_id" FOREIGN KEY (event_id) …
Run Code Online (Sandbox Code Playgroud) sql postgresql correlated-subquery sql-update postgresql-performance