Тестирование блокировки MySQL, работающей правильно - PullRequest
0 голосов
/ 03 ноября 2011

У меня есть таблица с именем events, которая содержит внутриигровые события, такие как строительство зданий, исследования и т. Д. Каждое событие имеет timestamp, указывающее, когда оно завершается.Engine: innoDB

При каждой загрузке страницы программа выполняет быстрый поиск в таблице events строк, где timestamp находится в прошлом (т. Е. Событие завершено).Он выбирает эти строки, а затем удаляет их, чтобы другие прогоны не видели и не обрабатывали одни и те же события.

Меня беспокоит то, что произойдет, если произойдет две страницы, чтобы они оба прочитали одни и те же строкидо того, как один или другой получит шанс удалить прочитанные строки, и что если событие произойдет прямо между выбором и удалением.

Я думаю, что это следует исправить:

SET @now=NOW();
SELECT * FROM `events` WHERE `timestamp` < @now FOR UPDATE
DELETE FROM `events` WHERE `timestamp` < @now

Но у меня возникли проблемы с тестированием.Как бы я проверил, работает ли это как надо?

1 Ответ

0 голосов
/ 03 ноября 2011

Собираюсь ответить на мой собственный вопрос здесь: p

Используйте sleep() между select и delete и выполняйте два вызова одновременно.

Финальный код:

START TRANSACTION
SET @now=NOW()
SELECT * FROM `events` WHERE `timestamp` < @now FOR UPDATE
-- SLEEP(5)
DELETE FROM `events` WHERE `timestamp` < @now

Результаты:

0,000: начало транзакции
0,001: выполнение запроса, возвращено 5 строк.
5.002: удалено 5 строк.
5.008: Завершение транзакции
===== Второй звонок, начался через пару секунд после первого:
0,000: начальная транзакция
2.562: Запрос выполнен, возвращено 0 строк.
2.562: удалено 0 строк.
2.562: Завершение транзакции

Это со сном. Без сна оба заканчиваются менее чем за 0,002 секунды.

...