Транзакционная безопасная вставка узла во вложенный набор? - PullRequest
1 голос
/ 28 июня 2010

Я храню иерархические данные в MySQL в форме вложенного набора.

myTable
  id,
  title,
  lft,
  rgt

Я использую следующую серию SQL-операторов для вставки нового узла:

SELECT @myLeft := lft FROM myTable WHERE ID = $id;  
UPDATE myTable SET rgt = rgt + 2 WHERE rgt > @myLeft;       
UPDATE myTable SET lft = lft + 2 WHERE lft > @myLeft;       
INSERT INTO myTable(title, lft, rgt) VALUES($title, @myLeft + 1, @myLeft + 2);

Это работает, но могут возникнуть проблемы, если много узлов будет добавлено (почти) одновременно.

Мне интересно, как лучше всего избежать повреждения данных (хранимые процедуры не подходят). Достаточно ли просто заключить этот sql в транзакцию? Должен ли я использовать транзакции, а также блокировку таблиц?

Спасибо

1 Ответ

1 голос
/ 28 июня 2010

Если вы используете таблицы MyISAM, вам придется заблокировать таблицу, поскольку таблицы MyISAM не поддерживают транзакции.

Для таблиц InnoDB вы можете выполнять всю работу в транзакции.1003 *

BEGIN; -- or whatever API your framework has for starting a transaction
SELECT @myLeft := lft FROM myTable WHERE ID = $id FOR UPDATE;  
UPDATE myTable SET rgt = rgt + 2 WHERE rgt > @myLeft;       
UPDATE myTable SET lft = lft + 2 WHERE lft > @myLeft;       
INSERT INTO myTable(title, lft, rgt) VALUES($title, @myLeft + 1, @myLeft + 2);
COMMIT; -- or whatever API your framework has for commiting a transaction
...