Задержка Handeling в транзакциях MySQL
Я пытаюсь понять, как правильно настроить транзакцию в базе данных и учесть потенциальную задержку.
НастройкаВ моем примере у меня есть таблица,users
keys
где каждый пользователь может иметь несколько ключей иconfig
таблица, которая определяет, сколько ключей может иметь каждый пользователь.
Я хочу запустить хранимую процедуру, которая:
выясняет, разрешено ли данному пользователю запрашивать ключ.получить доступный, невостребованный ключ.пытается выкупить ключ для данного пользователя.псевдокод для процедуры будет:
START TRANSACTION
(1) CALL check_permission(...,@result);
IF (@result = 'has_permission') THEN
(2) SET @unclaimed_key_id = (QUERY FOR RETURNING AVAILABLE KEY ID);
(3) CALL claim_key(@unclaimed_key_id);
END IF;
COMMIT;
Проблема, с которой я сталкиваюсь, состоит в том, что, когда я симулирую отставание после шага1
, (используяSELECT SLEEP()
), Это'Для данного пользователя возможно использовать несколько ключей, когда у них есть только разрешения на использование одного, запустив процедуру в нескольких сеансах до того, как первая процедура завершит свой сон (что опять-таки должно симулировать задержку)
Вот код длястолы а такжеПроцедуры (примечание: для небольшого примера я неЯ не использую индексы и внешние ключи, но, очевидно, я использую их в реальном проекте).
Чтобы увидеть мою проблему, просто настройте таблицы и процедуры в базе данных, затем откройте два терминала mysql и при первом запуске выполните следующее:
CALL `P_user_request_key`(10,1,@out);
SELECT @out;
И затем быстро (у вас есть 10 секунд) во втором запустить это:
CALL `P_user_request_key`(0,1,@out);
SELECT @out;
Оба запроса будут успешно возвращеныkey_claimed
и пользовательBob
в конечном итоге ему будут назначены 4 клавиши, хотя максимальное значение в конфигурации установлено на 3 для пользователя.