我担心数据库支持的应用程序中的竞争条件。我的应用程序允许用户在课堂上预留一个位置。如果拍摄了所有斑点,则将它们放在等候名单上。在大大简化的伪代码中,我做了类似的事情:
1 spots = SELECT total_spots FROM classes WHERE class_id = 200;
2 regs = SELECT COUNT(*) FROM registrations WHERE class_id = 200;
3 wl = spots > regs
4 INSERT INTO registrations ( user_id, class_id, on_waitlist ) VALUES ( 500, 200, wl );
如果在total_spots
表中更改了classes
,或者在我们读取它之后另一个用户在registrations
表上执行了INSERT会发生什么(第2行)。
将整个事物包装在事务中是否足够?我在MySQL中读过一些关于SELECT FOR UPDATE
的内容。我目前正在使用SQLite,但如果需要,我可以迁移到MySQL。
答案 0 :(得分:1)
SQLite的交易are fully atomic。
如果将整个事物包装在事务中,则同一数据库的其他连接不能同时进行任何更改。
答案 1 :(得分:1)
您也可以在插页中选择:
insert into registrations (user_id, class_id, on_waitlist)
values ( 500, 200,
(SELECT total_spots FROM classes WHERE class_id = 200) <
(SELECT COUNT(*) FROM registrations WHERE class_id = 200)
);