Це випливало з цього пов'язаного питання , де я хотів знати, як змусити дві транзакції послідовно відбуватися в тривіальному випадку (де обидва працюють лише в одному рядку). Я отримав відповідь - використовуйте 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 щодо того, наскільки реалістичним є наведений вище приклад, ось альтернативний сценарій: DBA підключається до живого сервера та працює
START TRANSACTION
SELECT ... FOR UPDATE
де другий рядок блокує рядок, до якого часто записує додаток. Потім DBA переривається і відходить, забуваючи закінчити транзакцію. Додаток перемелюється до зупинки, поки рядок не розблокується. Я хотів би мінімізувати час, коли програма застрягла внаслідок цієї помилки.
ROLLBACKпершою транзакцією, якщо на її виконання піде більше nсекунд. Чи можна це зробити?
MYSQLне має конфігурації, щоб запобігти цьому сценарію. Тому що це неприйнятно зависання сервера через безвідповідальність клієнтів. Я не знайшов жодних труднощів зрозуміти ваше запитання, також це так актуально.