2010-06-27 3 views
1

Я храню иерархические данные в 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

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

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

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