MySQL Server версии 5.1.41 с включенным плагином InnoDB. У меня есть следующие три таблицы для счетов-фактур: счета-фактуры, invoice_components и invoice_expenses. Таблица счетов имеет первичный ключ invoice_id. И invoice_components, и invoice_expenses связаны с накладными таблиц с invoice_id как неуникальным foreign_key (каждый счет может иметь более одного компонента и более одного расхода). Обе таблицы имеют индекс BTREE для этого внешнего ключа.
У меня есть следующие транзакции:
транзакция 1
START TRANSACTION;
SELECT * FROM invoices WHERE invoice_id = 18 FOR UPDATE;
SELECT * FROM invoice_components WHERE invoice = 18 FOR UPDATE;
SELECT * FROM invoice_expenses WHERE invoice = 18 FOR UPDATE;
Все работает нормально для первой транзакции, строки выбираются и блокируются.
транзакция 2
START TRANSACTION;
SELECT * FROM invoices WHERE invoice_id = 19 FOR UPDATE;
SELECT * FROM invoice_components WHERE invoice = 19 FOR UPDATE;
SELECT * FROM invoice_expenses WHERE invoice = 19 FOR UPDATE;
Вторая транзакция возвращает ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
для третьего запроса.
То же самое происходит, когда я пытаюсь ВЫБРАТЬ ... ДЛЯ ОБНОВЛЕНИЯ другие счета, их компоненты и расходы. Кажется, первая транзакция заблокировала все строки в таблице invoice_expenses. Есть идеи, почему это происходит?
Дополнительная информация
Транзакция 2 запускается после третьего запроса транзакции 1. На сервере нет других пользователей, соединений или транзакций.
Проблема возникает на уровне изоляции транзакции REPEATABLE READ по умолчанию. Это исправлено, если перейти на уровень READ COMMITTED. Это решение, но оно по-прежнему не объясняет, почему проблема возникает с invoice_expenses, а не с invoice_components.