У меня есть такая хранимая процедура:
DECLARE err_code CHAR(5) DEFAULT '00000';
DECLARE msg TEXT;
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
BEGIN
GET DIAGNOSTICS CONDITION 1
err_code = RETURNED_SQLSTATE, msg = MESSAGE_TEXT;
END;
START TRANSACTION;
INSERT INTO tableA .....;
INSERT INTO tableB .....;
SELECT updateJournal(id) INTO x;
IF err_code != '00000' THEN
ROLLBACK;
INSERT INTO log (msg) VALUES (msg);
ELSE
COMMIT;
END IF;
CREATE FUNCTION updateJournal(orderId INT) return int
BEGIN INSERT INTO tableC ....;
UPDATE tabled ....;
RETURN 1; END
иногда я получаю сообщение об ошибке «Обнаружена тупиковая ситуация при попытке получить блокировку; попробуйте перезапустить транзакцию»
хранимая процедура выполняет откат, но функция updateJournal все еще работает (tableC inserted, tableD updated),
Может ли кто-нибудь объяснить, почему хранимая процедура откатывается с ошибкой взаимоблокировки, но функция внутри хранимой процедуры все еще фиксируется.
может ли кто-нибудь объяснить, почему моя хранимая процедура вызывает ошибку взаимоблокировки?






Довольно сложно сказать, что вызывает тупик, основываясь только на предоставленной вами информации. Пока проблема возникает, вы можете попробовать собрать некоторую информацию. В Performance_schema есть несколько мест, которые могут содержать полезную информацию: Таблица data_locks, Таблица data_lock_waits , Таблица Metadata_locks
Убедитесь, что данные собираются, по умолчанию они не всегда собираются. В дополнение к этому, как уже упоминалось, вам следует захватить вывод
SHOW ENGINE INNODB STATUS\G
это также будет содержать некоторую полезную информацию о происходящих блокировках.
Вы можете получить все данные с помощью pt-stalk, инструмента из Percona Toolkit, который предназначен для проведения углубленного сбора данных, представляющих состояние базы данных. Вы можете скачать его с:
wget https://percona.com/get/pt-stalk
Вы можете запустить выполнение вручную:
./pt-stalk --no-stalk --iterations=1 --user=root --ask-pass
Данные, которые вы хотите просмотреть, находятся в файлах:
*-ps-locks-transactions
*-transactions
*-lock-waits
*-innodbstatus1
*-innodbstatus2
Не всегда все файлы будут созданы, это зависит от ситуации в базе данных. По умолчанию pt-stalk создает свои данные в /var/lib/pt-stalk.
Мы не можем сказать вам, почему ваш код заходит в тупик. Вам необходимо проверить монитор состояния innodb после получения ошибки взаимоблокировки, чтобы выяснить, что ее вызвало.