У меня есть две функции для создания имени виртуального пути из таблицы с именем tree_elements. Путь к функции (id, language) вызывается при любом обновлении таблицы. Время от времени обновление таблицы приводит к взаимоблокировкам с сообщением об ошибке (пример):
select path(621163,"de")
Deadlock found when trying to get lock; try restarting transaction
Я не понимаю, почему происходит блокировка. Функции используют только выбор, без обновления, без вставки, без удаления. Как я могу избежать этого явления?
Есть мои функции:
mysql> show create function path\G
*************************** 1. row ***************************
Function: path
sql_mode:
Create Function: CREATE DEFINER=`root`@`localhost` FUNCTION `path`(id integer, language char(2)) RETURNS varchar(255) CHARSET utf8
READS SQL DATA
DETERMINISTIC
COMMENT 'Converts a record id into an url string with path'
begin
declare ret varchar(255);
declare r varchar(255);
declare element varchar(255);
set ret = path_component(id,language);
set id = (select id_parent from tree_elements t where t.id=id);
while (id > 0) do
set element = concat(path_component(id,language), '/');
if (locate( element, ret )) then return concat( 'Infinite loop in path for id ', id ); end if;
set ret = concat(path_component(id,language), '/', ret );
set id = (select id_parent from tree_elements t where t.id=id);
end while;
return ret;
end
character_set_client: latin1
collation_connection: latin1_swedish_ci
Database Collation: utf8_general_ci
mysql> show create function path_component\G
*************************** 1. row ***************************
Function: path_component
sql_mode:
Create Function: CREATE DEFINER=`root`@`localhost` FUNCTION `path_component`( id integer, language char(2)) RETURNS varchar(500) CHARSET utf8
READS SQL DATA
DETERMINISTIC
begin
declare f varchar(255);
set f = (select case language
when 'en' then title_en
when 'de' then title_de
else title_en
end
from tree_elements t where t.id=id);
if (isnull(f) or length(trim(f)) = 0) then
set f = (select title_en from tree_elements t where t.id=id);
end if;
return url(f);
end
character_set_client: latin1
collation_connection: utf8_general_ci
Database Collation: utf8_general_ci