Это вытекает из этого связанного вопроса , где я хотел знать, как заставить две транзакции происходить последовательно в тривиальном случае (где обе работают только в одной строке). Я получил ответ - используйте 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нет конфигурации для предотвращения этого сценария. Потому что недопустимо зависание сервера из-за безответственности клиентов. Я не обнаружил затруднений в понимании вашего вопроса, и он так актуален.