Версия сервера MySQL 5.1.41 с включенным подключаемым модулем InnoDB. У меня есть следующие три таблицы для счетов-фактур: invoice, invoice_components и invoice_expenses. Таблица invoice имеет первичный ключ invoice_id. И invoice_components, и invoice_expenses связаны с таблицами invoice с 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;
Вторая транзакция возвращает ОШИБКА 1205 (HY000): Превышено время ожидания блокировки; попробуйте перезапустить транзакцию
для третьего запроса.
То же самое происходит, когда я пытаюсь ВЫБРАТЬ ... ДЛЯ ОБНОВЛЕНИЯ другие счета, их компоненты и расходы. Кажется, первая транзакция заблокировала все строки в таблице invoice_expenses. Есть идеи, почему это происходит?
Дополнительная информация
Транзакция 2 начинается после третьего запроса транзакции 1. На сервере нет других пользователей, подключений или транзакций.
Проблема возникает в ПОВТОРИЕМОМ ЧТЕНИИ по умолчанию. уровень изоляции транзакции. Исправляется переходом на уровень READ COMMITTED. Это решение, но оно все еще не объясняет, почему проблема возникает с invoice_expenses, а не с invoice_components.