У меня есть таблица MySQL (назовите ее «my_table») с составным первичным ключом с 4 столбцами (назовите их «a», «b», «c» и «d»).
По крайней мере, однажды я столкнулся с тупиковой ситуацией при параллельных асинхронных вызовах EJB, вызывающих 'УДАЛИТЬ ИЗ my_table, где a =? и b =?' с разными значениями, поэтому я начал изучать, как работает блокировка таблиц InnoDB.
Я не нашел четкой документации о том, как блокировка таблицы работает с составными ключами. Заблокирована ли вся таблица удалением, несмотря на то, что фактические удаляемые строки не перекрываются?
Нужно ли мне делать выбор, чтобы восстановить значения для c и d и удалить пакеты с использованием всего первичного ключа?
Это в контексте сложного приложения, которое работает с 4 разными базами данных. Кажется, только MySQL имеет эту проблему.






InnoDB никогда не блокирует всю таблицу для операторов DML. (Если DML не затрагивает все строки.)
Существуют и другие блокировки для операторов DDL, например, когда ALTER TABLE изменяет / добавляет столбцы / индексы / и т. д. (Некоторые из них были значительно ускорены в MySQL 8.0.)
Нет ничего особенного в блокировке составного ключа.
Есть штука, называемая «блокировкой зазора». По разным причинам «разрыв» между двумя значениями в индексе будет заблокирован. Это предотвращает потенциальные конфликты, такие как вставка того же значения новый, которое еще не существует, и есть ограничение уникальности.
Поскольку PRIMARY KEY - уникальный ключ, вы мая нажали что-то в этом роде.
Если возможно, сделайте SHOW ENGINE INNODB STATUS;, чтобы увидеть, является ли замок «зазором» или нет.
Еще одна вещь, которая может случиться, - это то, что блокировка может сначала быть слабой, а затем перерасти в «исключительную». Это может привести к тупиковой ситуации.
Do I need to do a select to recover the values for c and d and delete batches using the whole primary key?
Думаю, вам нужно более точно объяснить, что вы делаете. Введите запрос. Предоставьте SHOW CREATE TABLE.
Обработка блокировки InnoDB, возможно, уникальна для MySQL. В нем есть свои причуды. Иногда он немного жадно относится к тому, что блокирует; чтобы компенсировать это, возможно, быстрее, чем у конкурентов.
В любом случае проверяйте наличие тупиковых ситуаций (и тайм-аутов) и разбирайтесь с ними. Надежда на то, что эти проблемы достаточно редки, чтобы иметь дело с ними не слишком тяжело.
DELETE FROM my_table where a=? and b=? означает, что потенциально большое количество строк удаляется. Это означает, что журнал отмены и MVCC должны проделать большую работу. Следовательно, я рекомендую стараться не удалять (или обновлять) более 1 КБ строк за раз.
Спасибо за ответ, Рик. Рассматриваемая обработка включает несколько таблиц и, возможно, сотни тысяч строк в каждой. Целевые внешние ключи хранятся в том, что я назвал my_table. Они считываются и используются для создания строк в других таблицах, ссылающихся на рассматриваемые внешние ключи. Строки, прочитанные из my_table, удаляются. Если полная обработка не может быть завершена, ее следует откатить.