Это вытекает из этого связанного вопроса , где я хотел знать, как заставить две транзакции происходить последовательно в тривиальном случае (где обе работают только в одной строке). Я получил ответ - используйте SELECT ... FOR UPDATE
в качестве первой строки обе транзакции - но это приводит к проблеме: если первая транзакция никогда не фиксируется или не откатывается, то вторая транзакция будет заблокирована на неопределенный срок. innodb_lock_wait_timeout
Переменные задает число секунд , после чего клиент пытается сделать вторую сделку бы сказал « К сожалению, попробуйте еще раз» ... но насколько я могу сказать, что они не были бы попробовать еще раз до следующей перезагрузки сервера. Так:
- Наверняка должен быть способ форсировать,
ROLLBACK
если транзакция длится вечно? Должен ли я прибегать к использованию демона для уничтожения таких транзакций, и если да, то как бы выглядел этот демон? - Если соединение прерывается
wait_timeout
илиinteractive_timeout
выполняется транзакция в середине транзакции, выполняется ли откат транзакции? Есть ли способ проверить это с консоли?
Уточнение : innodb_lock_wait_timeout
задает количество секунд, в течение которых транзакция будет ожидать снятия блокировки, прежде чем отказаться; то, что я хочу, это способ заставить блокировку быть освобожденной.
Обновление 1 : Вот простой пример, который демонстрирует, почему innodb_lock_wait_timeout
этого недостаточно для того, чтобы вторая транзакция не была заблокирована первой:
START TRANSACTION;
SELECT SLEEP(55);
COMMIT;
При настройке по умолчанию innodb_lock_wait_timeout = 50
эта транзакция завершается без ошибок через 55 секунд. И если вы добавляете UPDATE
перед SLEEP
строкой, а затем инициируете вторую транзакцию от другого клиента, который пытается в SELECT ... FOR UPDATE
той же строке, это вторая транзакция, которая истекает, а не та, которая заснула.
То, что я ищу, - это способ положить конец спокойному сну этой транзакции.
Обновление 2 : В ответ на опасения hobodave о том, насколько реалистичен приведенный выше пример, приведем альтернативный сценарий: администратор БД подключается к работающему серверу и работает
START TRANSACTION
SELECT ... FOR UPDATE
где вторая строка блокирует строку, в которую приложение часто пишет. Затем администратор базы данных прерывается и уходит, забывая завершить транзакцию. Приложение останавливается, пока ряд не разблокируется. Я бы хотел минимизировать время, в течение которого приложение зависло в результате этой ошибки.
ROLLBACK
первую транзакцию, если она занимает больше n
секунды. Есть ли способ сделать это?
MYSQL
нет конфигурации для предотвращения этого сценария. Потому что недопустимо зависание сервера из-за безответственности клиентов. Я не обнаружил затруднений в понимании вашего вопроса, и он так актуален.