当更新基于先前选择的计数时,避免竞争条件

时间:2014-09-06 13:26:09

标签: sql sqlite

我担心数据库支持的应用程序中的竞争条件。我的应用程序允许用户在课堂上预留一个位置。如果拍摄了所有斑点,则将它们放在等候名单上。在大大简化的伪代码中,我做了类似的事情:

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。

2 个答案:

答案 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)
 );