Ger*_*umm 5 sql postgresql database-design
我正在写一个需要预订电影院座位的剧本.
由于可能有多个用户同时使用系统,我需要一种方法来"锁定"提供给当前客户端的行,直到某个时间过去,或者他请求另一个席位.
目前我将提供的座位标记为"已锁定"客户端ID,并使用SELECT将它们返回给客户端(这是针对MySQL,但目标数据库是Postgres)
UPDATE seats SET status = "locked", lock_time = NOW(), lock_id = "lock1" LIMIT 2
SELECT * FROM seats WHERE lock_id = "lock1" AND lock_time > DATE_SUB(NOW(), INTERVAL 2 MINUTE)
Run Code Online (Sandbox Code Playgroud)
有一个问题:如果只有一个座位可用,它仍然会被标记为"已锁定",我将立即释放锁定.
我也很确定有更聪明的方法.处理这样的任务的正确方法是什么?
竞争条件 - 我认为这作为插入而不是更新会更好。两个更新可以同时运行,并且不会相互冲突。如果您有“锁定座位”表,那么您可以引用 Seat_id 并使其唯一。这样竞争条件就会失败。但是,无论如何,我将其写为更新,就像您在问题中所做的那样,尽管您可以将其更改为插入。
如果没有足够的可用座位,您似乎一开始就不希望能够锁定座位。使用自连接这很容易:
create temp table seats
(
id serial,
event_id integer,
locked boolean default false
);
insert into seats (event_id) values (1),(1),(1),(2);
-- this will not lock event_id = 2 since it will not have a high enough count
update seats
set locked = true
from
(
-- get the counts so we can drop events without enough seats
select count(*), event_id from seats group by event_id
) as sum,
(
-- you can not put limits in update; need to self-join
select id from seats limit 2
) as t
where sum.event_id = seats.event_id
and seats.id = t.id
and count >= 2
Run Code Online (Sandbox Code Playgroud)
;
UPDATE 2
id | event_id | locked
----+----------+--------
3 | 1 | f
4 | 2 | f
2 | 1 | t
1 | 1 | t
(4 rows)
Run Code Online (Sandbox Code Playgroud)
因此,这会为每个至少有两个座位的活动“锁定”两个座位:)
| 归档时间: |
|
| 查看次数: |
5093 次 |
| 最近记录: |