このシナリオでは、次の操作の一貫性をどのように許可するかについて苦労しています。コースにサインインできる予約ポータルを開発しています。すべてのコースには多数の直接予約があります:利用可能な予約が終わったら、ユーザーはまだサインすることができますが、待機リストには秋です。並行環境でMYSQLテーブルを正しくロックする方法
これは状況です:たとえば、コースに15スロットがあり、予約しているとします。シンプルなロジックでは、私が予約をしたとき、システムは私がダイレクト予約リスト(利用可能な15のスロットの1つ)または待機リストにあるかどうかを判断する必要があります。総直接予約が可能な合計の予約よりも小さい場合、そうするためには、我々はカウントしなければならない、擬似コードでこのようなものは:
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
質問です:私は確かであるために、同時実行を管理する方法2つのサブスクリプションは正しく管理されていますか? 1つの予約が残っていて、2人のユーザーが同時に適用される場合、COUNT操作の結果によって両方の要求に同じ結果が与えられ、両方のユーザーがリストに挿入される可能性があります。
ユーザーがサブスクリプション手順を開始した場合、要求が完了する前に誰も同じタスクを完了できないようにするには、正しいロック方法(または同様の手順)は何ですか?の場合には、
INSERT
INSERT INTO table1 (field1, field2, ..., fieldN, flag_direct_reservation)
SELECT @field1, @field2, ..., @fieldN, ,CASE WHEN (SELECT COUNT(*) FROM sometable WHERE [email protected]_id) > @max_part THEN 1 ELSE 0 END
のみのサブスクリプション・ステータスを決定するためのUPDATE (:
[OK]を、まだコメントが感謝、我々はロックせずに解決策を見つけたようですサブスクリプション削除)
UPDATE corsi_mytable p1 INNER JOIN
(
SELECT COUNT(*) as actual_subscritions
FROM mytable
WHERE [email protected]_id
)p2
SET p1.flag_direct_reservation= CASE WHEN p2.actual_subscritions > @max_part THEN 0 ELSE 1 END
WHERE p1.id [email protected]_waiting_id;
このように、操作は1つのSQL文でのみ実行され、トランザクションエンジンは操作の一貫性を保証する必要があります。
しばらくの間活動がありませんでした。あなたは答えを受け入れることができますか? – RaphaMex