如何在并发环境中正确锁定MYSQL表

如何在并发环境中正确锁定MYSQL表,mysql,locking,Mysql,Locking,在这个场景中,我正在为如何保证以下操作的一致性而苦苦挣扎:我们正在开发一个预订门户,您可以在那里注册课程。每门课程都有一些直接预订:当可用的预订结束时,用户仍然可以签名,但会在等待名单中下降 所以情况就是这样:例如,让我们假设一个课程有15个可用的时段,我进行了预订。在一个简单的逻辑中,当我进行预订时,系统必须决定我是在15个可用插槽中的直接预订列表中还是在等待列表中。为了做到这一点,我们必须计算总直接预订量是否小于总可用预订量,如伪代码中所示: INSERT new_partecipant I

在这个场景中,我正在为如何保证以下操作的一致性而苦苦挣扎:我们正在开发一个预订门户,您可以在那里注册课程。每门课程都有一些直接预订:当可用的预订结束时,用户仍然可以签名,但会在等待名单中下降

所以情况就是这样:例如,让我们假设一个课程有15个可用的时段,我进行了预订。在一个简单的逻辑中,当我进行预订时,系统必须决定我是在15个可用插槽中的直接预订列表中还是在等待列表中。为了做到这一点,我们必须计算总直接预订量是否小于总可用预订量,如伪代码中所示:

INSERT new_partecipant IN table_partecipants;
(my_id) = SELECT @@IDENTITY;
(total_reservations_already_made) = SELECT COUNT(*) FROM table_partecipants WHERE flag_direct_reservation=1;
if total_reservations_already_made <= total_reservations_available then
UPDATE table_partecipants SET flag_direct_reservation=1 WHERE id=my_id
更新 仅用于在订阅删除的情况下确定订阅状态


这样,操作仅由一条SQL语句执行,事务引擎应确保操作的一致性。

我建议您再次为此锁定完整表。找一个排锁

您可以有一个单独的表,该表只有一行,您的预订计数器为15,并在添加新预订之前更新此计数器。
因此,您可以确定锁是由这个单独的表管理的,它使您的预订表能够在您不关心计数器的任何其他情况下更新。

不要锁定表。相反,试着预定一排,如果排不上,就把他们放在等待名单上。例如:

UPDATE table_partecipants SET booking_id=? WHERE booking_id IS NULL LIMIT 1
这里的WHERE条款应该包括任何其他排除因素,比如如果是正确的一天。如果查询成功修改了一行,则预订工作正常。如果没有,它就卖完了。不需要锁


这里的预订id是一些独特的值,可用于将本课程与预订人关联。您可以删除因超额预订而未使用的任何记录。

已经有一段时间没有活动了。你能接受答案吗?
UPDATE corsi_mytable p1 INNER JOIN 
(
    SELECT COUNT(*) as actual_subscritions
    FROM mytable
    WHERE course=@course_id
)p2 
SET p1.flag_direct_reservation= CASE WHEN p2.actual_subscritions > @max_part THEN 0 ELSE 1 END 
WHERE p1.id =@first_waiting_id;
UPDATE table_partecipants SET booking_id=? WHERE booking_id IS NULL LIMIT 1