Это отличная возможность для возникновения всевозможных сумасшедших ошибок, а некоторые из них могут вызвать проблемы с производительностью.
Классическим решением было бы использование транзакций (http://dev.mysql.com/doc/refman/5.0/en/commit.html). Это позволяет вам гарантировать согласованность ваших данных - но длительная транзакция в базе данных превращает ее в огромное узкое место; если вы "находите тайм-аут сеансов" "код выполняется в течение минуты, транзакция может выполняться в течение всего этого периода, эффективно блокируя доступ для записи в затронутые таблицы. Большинство систем не справятся с этим.
Мое любимое решение для такой ситуации - иметь «конечный автомат» для статуса; Мне нравится реализовывать это как таблицу истории, но это, как правило, приводит к быстро растущей базе данных.
Вы определяете состояния сеанса как «инициированный», «запущенный», «тайм-аут - закрытие», «тайм-аут - закрыто» и «остановлен пользователем» (например).
Вы реализуете код, который учитывает логику перехода состояний в любой имеющейся у вас логике доступа к данным. Тогда псевдокод для вашего сценария «очистки» может быть следующим:
- обновить все записи, чье время окончания
- для каждой записи, статус которой «тайм-аут - закрытие»
- делай все, что тебе нужно
- обновить эту запись, чтобы установить статус «тайм-аут - закрыто», где статус = «тайм-аут - закрытие»
- следующая запись
Все остальные попытки изменить текущее состояние записи сеанса должны проверять, является ли текущий статус действительным для предпринятого изменения.
Например, «ручной» код остановки должен выглядеть примерно так:
update sessions
set status = "stopped by user"
where session_id = xxxxx
and status = 'running'
Если подпрограмма автоматического закрытия была запущена во время между отображением пользовательского интерфейса и кода базы данных, предложение where не будет соответствовать ни одной записи, поэтому остальная часть кода просто не запускается.
Чтобы это работало, весь код, который изменяет состояние сеанса, должен проверить его предварительные условия; Наиболее удобный способ - это кодировать статус и разрешенные переходы в отдельную таблицу базы данных.
Вы также можете написать триггеры для обеспечения этой логики, хотя я обычно не фанат триггеров - делайте это только если вам нужно.
Я не думаю, что это добавляет значительных проблем с производительностью - но тестируйте и оптимизируйте. Большая часть дополнительной работы с базой данных заключается в добавлении дополнительных выражений «где» в ваши операторы обновления; при условии, что у вас есть индекс статуса, вряд ли это окажет ощутимое влияние.